我正在使用 Netezza SQL。
我有一个表(“my_table”),其中包含以下信息:
- student_id(例如 123、124 等)
- 奖学金(1 = 是,0 = 否):请注意,学生可以在一年内获得奖学金并在下一年失去奖学金(反之亦然) - 但在同一年内,学生不能更改其奖学金状态
- year_parking_ticket_recieved(同一学生可以在同一年收到多张 parking 罚单)
- year_parking_ticket_paid(支付罚单的年份必须始终大于或等于收到罚单的年份)
表格如下所示:
student_id scholarship year_parking_ticket_received year_parking_ticket_paid
1 1 1 2010 2015
2 1 1 2011 2015
3 1 0 2012 2016
4 1 1 2012 2016
5 2 0 2020 2023
6 2 0 2021 2023
7 2 0 2018 2023
8 2 0 2017 2023
我正在尝试创建一个摘要,显示有多少学生(奖学金 = 1 与奖学金 = 0)每年确切支付了多少张 parking 罚单(即year_paid)。举个例子:
- 2010 年,23 名不同的获得奖学金的学生每人只支付了一张门票
- 2010 年,13 名获得奖学金的不同学生每人支付了 2 张门票
- 2011 年,19 名没有奖学金的不同学生每人支付了 4 张门票
- 等等
最终结果如下所示:
scholarship year_paid number_of_parking_tickets number_of_students_that_paid_exactly_this_number_of_tickets
1 1 2010 1 23
2 1 2010 2 14
3 1 2011 3 19
4 0 2010 1 20
我的问题:我和一个 friend 一直在试图找出解决这个问题的正确方法。
这是我的方法:
with cte as
(select student_id,
year_parking_ticket_paid, scholarship,
count(distinct year_parking_ticket_received) as distinct_year
from my_table
group by student_id, year_parking_ticket_paid, scholarship),
cte2 as (
select year_parking_ticket_paid, distinct_year, sum(distinct_year) as count_distinct_year, scholarship
from cte
group by year_parking_ticket_paid, distinct_year, scholarship)
select * from cte2
这是我 friend 的方法:
select year_parking_ticket_paid, number_of_parking_tickets, count(*)
from
(
select student_id, year_parking_ticket_paid, sum(scholarship) as schol, count(*) as number_of_parking_tickets
from my_table
group by student_id, year_parking_ticket_paid
) as a
group by year_parking_ticket_paid, number_of_parking_tickets
我们都对哪种方法才是解决这个问题的正确方法感到困惑 - 有人可以帮助我们吗?
谢谢!
- 注意:如果学生 123 在 2010 年支付了 4 张门票...他不会为 2010 年 & 1 张门票、2010 年 & 2 张门票、2010 年 & 3 张门票的行捐款...他只会为 2010 年的行捐款&4张门票
- 注意:奖学金变量与支付 parking 罚单的年份有关
最佳答案
第二个(基于子查询)查询不正确,因为输出不区分奖学金状态。
第一个(基于 CTE 的)查询写得不好,因为它不需要 distinct
,并且应该将 CTE 转换为子查询。
永远不要将表命名为 my_table
。不要将奖学金状态表示为 int
;将其表示为 bool 值。另请注意,scholarship
位于有关 parking 记录的表中是标准化失败,应移至 student
表;但我还没有展示这一点。
create table tickets(
student_id int not null,
scholarship boolean not null,
year_parking_ticket_received smallint not null,
year_parking_ticket_paid smallint
);
insert into tickets
(student_id, scholarship, year_parking_ticket_received, year_parking_ticket_paid) values
( 1, true, 2010, 2015),
( 1, true, 2011, 2015),
( 1, false, 2012, 2016),
( 1, true, 2012, 2016),
( 2, false, 2020, 2023),
( 2, false, 2021, 2023),
( 2, false, 2018, 2023),
( 2, false, 2017, 2023);
select *, count(*) as n_instances
from (
select year_parking_ticket_paid, scholarship, count(*) as n_tickets
from tickets
group by year_parking_ticket_paid, scholarship, student_id
) ticket_counts
group by year_parking_ticket_paid, scholarship, n_tickets
order by year_parking_ticket_paid;
year_parking_ticket_paid scholarship n_tickets n_instances
2015 t 2 1
2016 f 1 1
2016 t 1 1
2023 f 4 1
关于SQL:了解这两个查询之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76742190/