SQL:了解这两个查询之间的区别

标签 sql

我正在使用 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/

相关文章:

php - 将行与 mysql 中的最新日期连接起来

sql - 字符串的 PostgreSQL 部分在数组中

SQL MAX() 函数

mysql - 更新表中包含特定值的所有字段

sql - 为什么 select top ... order by 索引列仍然排序?

mysql - 我想根据 mysql 中的 YES OR NO NAME GROUP BY NAME 计算 ETR_MEET PERCENT

sql - 甲骨文 SQL : How to write below SQL in Oracle

sql - 为什么SQLite3使用覆盖索引而不是我创建的索引?

sql - 如何从列表中删除所有重复的对?

mysql - SQL 三表返回一行