我尝试创建一个返回以下结果集的查询(为了便于阅读而被截断):
+---------------+-----------+--------+--------+----------+
| DATE_HAPPENED | Twelve_AM | One_AM | Two_AM | Three_AM | (and so on, until 24 hours)
+---------------+-----------+--------+--------+----------+
| 2015-10-01 | 110 | 34 | 92 | 45 |
+---------------+-----------+--------+--------+----------+
这是我使用的代码(我不确定它是最好的方法):
SELECT to_char(potty_use_date, 'yyyy-mm-dd HH12') as date_happened,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 AM') = '12' THEN 1 ELSE 0 END) as Twelve_AM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 AM') = '1' THEN 1 ELSE 0 END) as One_AM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 AM') = '2' THEN 1 ELSE 0 END) as Two_AM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 AM') = '3' THEN 1 ELSE 0 END) as Three_AM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 AM') = '4' THEN 1 ELSE 0 END) as Four_AM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 AM') = '5' THEN 1 ELSE 0 END) as Five_AM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 AM') = '6' THEN 1 ELSE 0 END) as Six_AM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 AM') = '7' THEN 1 ELSE 0 END) as Seven_AM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 AM') = '8' THEN 1 ELSE 0 END) as Eight_AM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 AM') = '9' THEN 1 ELSE 0 END) as Nine_AM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 AM') = '10' THEN 1 ELSE 0 END) as Ten_AM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 AM') = '11' THEN 1 ELSE 0 END) as Eleven_AM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 PM') = '1' THEN 1 ELSE 0 END) as One_PM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 PM') = '2' THEN 1 ELSE 0 END) as Two_PM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 PM') = '3' THEN 1 ELSE 0 END) as Three_PM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 PM') = '4' THEN 1 ELSE 0 END) as Four_PM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 PM') = '5' THEN 1 ELSE 0 END) as Five_PM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 PM') = '6' THEN 1 ELSE 0 END) as Six_PM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 PM') = '7' THEN 1 ELSE 0 END) as Seven_PM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 PM') = '8' THEN 1 ELSE 0 END) as Eight_PM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 PM') = '9' THEN 1 ELSE 0 END) as Nine_PM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 PM') = '10' THEN 1 ELSE 0 END) as Ten_PM,
COUNT(CASE WHEN to_char(potty_use_date, 'HH12 PM') = '11' THEN 1 ELSE 0 END) as Eleven_PM,
CASE WHEN to_char(potty_use_date, 'HH12 PM') = '12' THEN 1 ELSE 0 END) as Twelve_PM
FROM core.potty_usage_statistics
GROUP BY to_char(potty_use_date, 'yyyy-mm-dd HH12')
ORDER BY date_happened ASC;
但是,我得到了以下结果:
2015-04-20 08 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197 1197
他们在结果窗口中全部重复。显然,我没有做到这一点。我该怎么做?
答案 0 :(得分:2)
COUNT()
计算非NULL
值的数量。如果值为0或1,则所有值均为非NULL
。因此,计数与COUNT(*)
相同。
两个选项:
COUNT()
更改为SUM()
ELSE 0
就个人而言,我更喜欢第一种方法;但要么是可行的。
我还应该注意,您可以将EXTRACT()
用于此目的:
SUM(CASE WHEN extract(hour from potty_use_date) = 0 THEN 1 ELSE 0 END) as Midnight,
有些人可能会觉得这更容易阅读。
我还怀疑您希望GROUP BY
和SELECT
为:
SELECT to_char(potty_use_date, 'yyyy-mm-dd') as date_happened
. . .
GROUP BY to_char(potty_use_date, 'yyyy-mm-dd')
如果您包含小时组件,那么您将获得一个对角线值,每天24行,每个列都填充一小时列。
答案 1 :(得分:2)
也许你可以转动:
select * from
(
select
trunc(p.potty_use_date) as potty_use_date,
to_char(p.potty_use_date, 'HH24') as putty_use_hour,
from
core.potty_usage_statistics p
)
pivot (
count(putty_use_hour)
for putty_use_hour in (
'00' as "Midnight", '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11',
'12' as "Noon", '13', '14', '15', '16', '17', '18' as "Dinner time", '19', '20', '21', '22', '23', '24' as "Or is this midnight")
)
我手头没有Oracle,所以我无法测试它,但这应该可行。
有关在Oracle中进行透视的详细信息,以及为什么需要整个小时列表的说明,请阅读SQL Operations: Pivot and Unpivot