假设我有一个记录用户活动的SQL Server表。假设它具有用户ID,用户名,活动日期和活动类型列。我想打印出所有用户活动的列表,每个月的活动有一行,每个活动类型的列总结了该月活动发生的次数。我正在尝试使用以下查询执行此操作:
SELECT
user_id,
user_name,
CONVERT(VARCHAR(7), activity_date, 120),
SUM(CASE WHEN activity_type = 'Log In' THEN 1 ELSE 0 END),
SUM(CASE WHEN activity_type = 'Save Document' THEN 1 ELSE 0 END),
SUM(CASE WHEN activity_type = 'Create Document' THEN 1 ELSE 0 END)
FROM UserActivity
WHERE DATE BETWEEN '11-1-2010 00:00:00' AND '12-31-2010 23:59:59'
GROUP BY user_id, user_name, CONVERT(VARCHAR(7), activity_date, 120)
问题是,这个查询基本上为每个活动提供了一个单独的行 - 很多很多行,没有计数。我认为问题在于我正在做日期的方式,因为如果我将查询更改为不选择日期,我会得到一个看起来“大多正确”的表。
有什么想法吗?
答案 0 :(得分:1)
如果没有GROUP BY,则不能使用SUM,至少不能使用SELECT中的其他非聚合。正确执行GROUP BY子句。
SELECT
user_id,
user_name,
CONVERT(VARCHAR(7), activity_date, 120),
SUM(CASE WHEN activity_type = 'Log In' THEN 1 ELSE 0 END),
SUM(CASE WHEN activity_type = 'Save Document' THEN 1 ELSE 0 END),
SUM(CASE WHEN activity_type = 'Create Document' THEN 1 ELSE 0 END)
FROM UserActivity
WHERE DATE BETWEEN '11-1-2010 00:00:00' AND '12-31-2010 23:59:59'
GROUP BY user_id,
user_name,
CONVERT(VARCHAR(7), activity_date, 120)
对于它的价值,对于日期范围,我更喜欢使用
WHERE DATE >= '20101101'
AND DATE < '20110101'
我确信丢失一些时间戳为'12 -31-2010 23:59:59.997'的记录无关紧要,但使用< next_date
测试更符合逻辑。无论区域/语言/日期格式设置如何,格式YYYYMMDD都是最强大的。