获取所有driver个等于每个记过码最大违规数的牌照号码
Getting all the driver license numbers who have equal to the maximum amount of offences for each demerit code
我正在为一个单项任务做这个,任务是基本上获得所有 driver 个许可证号码,这些号码等于每个记过代码的最大违规数。
因此存在违规 table、记过 table 和 drivers table,并且查询应该 return 所有 drivers 许可证获得了每个过失类别最多的罚单,如果最大值相同,return 获得该过失类别最高罚单的所有 drivers 许可证。
我使用了一个超级丑陋的嵌套子查询设置,如下所示:
select
sp.dem_code as "Demerit Code",
dem.dem_description as "Demerit Description",
sp2.lic_no as "License No.",
d.lic_fname || ' ' || d.lic_lname as "Driver Fullname",
sp."Total Times Booked"
from (
select
dem_code,
max(o.num) as "Total Times Booked"
from (
select
dem_code,
count(lic_no) as num,
lic_no
from offence
group by dem_code, lic_no
order by dem_code asc
) o
group by dem_code
order by dem_code asc
) sp
join (
select
dem_code,
count(lic_no) as num,
lic_no
from offence
group by dem_code, lic_no
order by dem_code asc
) sp2 on sp."Total Times Booked" = sp2.num and sp.dem_code = sp2.dem_code
join driver d on sp2.lic_no = d.lic_no
join demerit dem on dem.dem_code = sp2.dem_code
order by sp.dem_code asc, sp2.lic_no asc
;
但我不明白为什么会这样:
select
dem_code,
max(num),
lic_no
from (
select dem_code, count(lic_no) as num, lic_no from offence group by dem_code, lic_no order by dem_code asc
)
group by dem_code
;
或
select
dem_code,
max(num),
lic_no
from (
select dem_code, count(lic_no) as num, lic_no from offence group by dem_code, lic_no
)
group by dem_code
having num = max(num)
order by dem_code asc
;
不行吗?
它基本上归结为获取所有等于该组错误代码最大值的许可证号。
为什么 pl/sql 可以用 SQL :D
假设 table 进攻是...
(
dem_code varchar2(100),
lic_no varchar2(100),
lic_fname varchar2(100),
... ticket_no varchar2(1),
... ticket_dtls varchar2(1000),
...
);
需要两个级别的 SQL 分析 Window 函数(按照我的说法)。
- 计算每人每个记过代码的总数。
- 计算每个记过代码的最大违规次数或针对相同记过代码的所有人的最大值(每人记过总数)。
我们不能在 where 子句中使用 Window 函数,因此需要 Q1 和 Q2 作为两个连续的计算层(输入管道 -> Q1 -> Q2 -> 结果集)。
查询:
With Q1 as (
select
dem_code,
lic_no,
lic_fname,
-- count per person per demerit code
count(1) over (partition by dem_code, lic_fname) as fname_dc_num
from offence
),
Q2 as (
select
dem_code,
lic_no,
lic_fname,
fname_dc_num,
-- max count by any person for demerit code
max(fname_dc_num) keep (DENSE_RANK FIRST ORDER BY fname_dc_num desc) over (partition by dem_code) as max_dc_num
from Q1
)
select *
from Q2
where fname_dc_num = max_dc_num
order by dem_code asc, lic_no, lic_fname
;
我正在为一个单项任务做这个,任务是基本上获得所有 driver 个许可证号码,这些号码等于每个记过代码的最大违规数。
因此存在违规 table、记过 table 和 drivers table,并且查询应该 return 所有 drivers 许可证获得了每个过失类别最多的罚单,如果最大值相同,return 获得该过失类别最高罚单的所有 drivers 许可证。
我使用了一个超级丑陋的嵌套子查询设置,如下所示:
select
sp.dem_code as "Demerit Code",
dem.dem_description as "Demerit Description",
sp2.lic_no as "License No.",
d.lic_fname || ' ' || d.lic_lname as "Driver Fullname",
sp."Total Times Booked"
from (
select
dem_code,
max(o.num) as "Total Times Booked"
from (
select
dem_code,
count(lic_no) as num,
lic_no
from offence
group by dem_code, lic_no
order by dem_code asc
) o
group by dem_code
order by dem_code asc
) sp
join (
select
dem_code,
count(lic_no) as num,
lic_no
from offence
group by dem_code, lic_no
order by dem_code asc
) sp2 on sp."Total Times Booked" = sp2.num and sp.dem_code = sp2.dem_code
join driver d on sp2.lic_no = d.lic_no
join demerit dem on dem.dem_code = sp2.dem_code
order by sp.dem_code asc, sp2.lic_no asc
;
但我不明白为什么会这样:
select
dem_code,
max(num),
lic_no
from (
select dem_code, count(lic_no) as num, lic_no from offence group by dem_code, lic_no order by dem_code asc
)
group by dem_code
;
或
select
dem_code,
max(num),
lic_no
from (
select dem_code, count(lic_no) as num, lic_no from offence group by dem_code, lic_no
)
group by dem_code
having num = max(num)
order by dem_code asc
;
不行吗?
它基本上归结为获取所有等于该组错误代码最大值的许可证号。
为什么 pl/sql 可以用 SQL :D
假设 table 进攻是...
(
dem_code varchar2(100),
lic_no varchar2(100),
lic_fname varchar2(100),
... ticket_no varchar2(1),
... ticket_dtls varchar2(1000),
...
);
需要两个级别的 SQL 分析 Window 函数(按照我的说法)。
- 计算每人每个记过代码的总数。
- 计算每个记过代码的最大违规次数或针对相同记过代码的所有人的最大值(每人记过总数)。
我们不能在 where 子句中使用 Window 函数,因此需要 Q1 和 Q2 作为两个连续的计算层(输入管道 -> Q1 -> Q2 -> 结果集)。
查询:
With Q1 as (
select
dem_code,
lic_no,
lic_fname,
-- count per person per demerit code
count(1) over (partition by dem_code, lic_fname) as fname_dc_num
from offence
),
Q2 as (
select
dem_code,
lic_no,
lic_fname,
fname_dc_num,
-- max count by any person for demerit code
max(fname_dc_num) keep (DENSE_RANK FIRST ORDER BY fname_dc_num desc) over (partition by dem_code) as max_dc_num
from Q1
)
select *
from Q2
where fname_dc_num = max_dc_num
order by dem_code asc, lic_no, lic_fname
;