[英]sql: group by multiple correlated fields (date, weekday, month)
我正在执行SQL任务。 目的是从航班表中获知在给定月份的给定日期内平均有多少个航班。
输入表:航班
id BIGINT
dep_day_of_week varchar (255)
dep_month varchar (255)
dep_date text
航班表的示例。 同一日期可能有多个条目。
id dep_day_of_week dep_month dep_date
1 Thursday January 4/7/2005 15:24:00
2 Friday February 5/6/2005 12:12:12
3 Friday February 5/6/2005 15:12:12
我阅读了以下解决方案:
SELECT a.dep_month,
a.dep_day_of_week,
AVG(a.flight_count) AS average_flights
FROM (
SELECT dep_month, dep_day_of_week, dep_date,
COUNT(*) AS flight_count
FROM flights
GROUP BY 1,2,3
) a
GROUP BY 1,2
ORDER BY 1,2;
我的问题在子查询中,该子查询计算每天的航班数量:
SELECT dep_month, dep_day_of_week, dep_date, COUNT(*) AS flight_count
FROM flights
GROUP BY 1,2,3
由于dep_month , dep_day_of_week和dep_date是三个相关属性,因此dep_date可能是这三个属性中最详细的解决方案。 所以我认为GROUP BY 1,2,3
的功能与GROUP BY 3
相同。
为了检查可能存在的差异,我使用count(*) from ..
。 选择以上子查询产生的所有术语,
Select count(*) from (
SELECT dep_month, dep_day_of_week, dep_date, COUNT(*) AS flight_count
FROM flights
GROUP BY 1,2,3 or Group Group by 3)
在输出中, GROUP BY 1,2,3
和GROUP BY 3
的计数分别为447和441。 为什么这两种分组方法之间有区别?
更新:
感谢@trincot出色的回答。 我使用他的建议代码,并在输入数据库中发现不一致之处。
SELECT dep_date, count(distinct dep_month), count(distinct dep_day_of_week)
FROM flights
GROUP BY dep_date
HAVING count(distinct dep_month) > 1
OR count(distinct dep_day_of_week) > 1
输出:
dep_date count(distinct dep_month) count(distinct dep_day_of_week)
1/16/2001 1 2
10/25/2003 1 2
2/23/2000 1 2
3/29/2001 1 2
4/3/2001 1 2
5/13/2000 1 2
具体而言,数据库分配周一1/16/2001 8:25:00
和周二1/16/2001 7:56:00
。 这就是不一致的原因。
由于日期字段具有时间成分,因此子查询中的count(*)
每次将为1,因为时间成分将有所不同并生成一个新组。 您的群组实际上是每秒。
您可以在没有子查询的情况下获得结果,如下所示:
select dep_month,
dep_day_of_week,
count(*) /
count(distinct substring_index(dep_date, ' ', 1)) avg_flights
from flights
group by dep_month,
dep_day_of_week
这将计算所有的排期记录,并将其除以这些排期的不同日期数。 仅通过在空格之前输入部分来提取日期。
请注意,这意味着当您完全没有某个日期的记录时,这一天将不会计入平均值,并可能给人留下错误的印象。 例如,如果在一月份只有一个星期五可供您乘搭航班(假设其中有十个航班),但是一月份有四个星期五,您仍然可以平均乘以10,即使2.5更为合理。
您声明此查询返回447条记录:
Select count(*) from (
SELECT dep_month, dep_day_of_week, dep_date, COUNT(*) AS flight_count
FROM flights
GROUP BY 1,2,3)
而这只有441:
Select count(*) from (
SELECT dep_month, dep_day_of_week, dep_date, COUNT(*) AS flight_count
FROM flights
GROUP BY 3)
这似乎表明您在多个记录中具有相同的日期,但是前两列之一却有所不同,这将是不一致的。 您可以通过以下查询找到答案:
SELECT dep_date, count(distinct dep_month), count(distinct dep_day_of_week)
FROM flights
GROUP BY dep_date
HAVING count(distinct dep_month) > 1
OR count(distinct dep_day_of_week) > 1
在健康的数据集中,此查询应返回0条记录。 如果返回记录,则将获得至少一个记录中未正确设置月份的日期,或者至少一个记录中未正确设置星期几的日期。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.