如何解决一天中的所有时间
| 在我的sql查询中,我计算一天中每个小时的订单数。我的查询看起来像这样:SELECT COUNT(dbo.Uputa.ID),{ fn HOUR(dbo.Orders.Date) } AS Hour
FROM Orders
WHERE dbo.Orders.Date BETWEEN \'2011-05-01\' AND \'2011-05-26\'
GROUP BY { fn HOUR(dbo.Orders.Date) }
ORDER BY Hour
我的问题是查询仅返回dbo.Orders.Date中的现有Hours。
例如:
Number Hour
12 3
12 5
我想像这样返回所有时间:
Number Hour
0 0
0 1
0 2
12 3
0 4
12 5
...
0 23
有人知道如何做到这一点吗?
解决方法
使用公共表格表达式创建所有小时数,然后左键合并分组的总数以得到结果。
with mycte as
(
SELECT 0 AS MyHour
UNION ALL
SELECT MyHour + 1
FROM mycte
WHERE MyHour + 1 < 24
)
SELECT mycte.MyHour,COALESCE(OrderCount,0) FROM mycte
LEFT JOIN
(
SELECT COUNT(dbo.Uputa.ID) AS OrderCount,{ fn HOUR(dbo.Orders.Date) } AS MyHour
FROM Orders
WHERE dbo.Orders.Date BETWEEN \'2011-05-01\' AND \'2011-05-26\'
GROUP BY { fn HOUR(dbo.Orders.Date) }
) h
ON
h.MyHour = mycte.MyHour;
,通常,数据库中有一个“数字表”(例如,SQL,数字的辅助表),是一件非常有用的事情。如果您在此处创建一个,则可以从数字表中选择0到23之间的所有行,将结果与结果左连接,就可以得到想要的结果,而无需为此查询创建自定义CTE或类似内容。
SELECT COUNT(dbo.Uputa.ID),n.number AS Hour
FROM (select number from numbers where number between 0 and 23) n
left join Orders o on n.number={ fn HOUR(dbo.Orders.Date) }
WHERE dbo.Orders.Date BETWEEN \'2011-05-01\' AND \'2011-05-26\'
GROUP BY n.number
ORDER BY n.number
(为了清楚起见,我已按照您的示例说明了这一点,但实际上,我会尽量避免将函数放入联接条件中以最大化性能。)
,您可以使用CTE
添加缺失的小时数,并使用JOIN
与原始查询中的空格相加。
SQL语句
;WITH q (Number,Hour) AS (
SELECT 0,1
UNION ALL
SELECT q.Number,q.Hour + 1
FROM q
WHERE q.Hour < 23
)
SELECT COALESCE(o.Number,q.Number),q.Hour
FROM q
LEFT OUTER JOIN (
SELECT COUNT(dbo.Uputa.ID),{ fn HOUR(dbo.Orders.Date) } AS Hour
FROM Orders
WHERE dbo.Orders.Date BETWEEN \'2011-05-01\' AND \'2011-05-26\'
GROUP BY { fn HOUR(dbo.Orders.Date) }
) o ON o.Hour = q.Hour
ORDER BY
q.Hour
测试脚本
;WITH Orders (Number,Hour) AS (
SELECT 12,3
UNION ALL SELECT 12,5
),q (Number,q.Hour
FROM q
LEFT OUTER JOIN Orders o ON o.Hour = q.Hour
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。