在SQL Server中遇到问题

时间:2011-02-22 20:20:56

标签: sql sql-server datetime

假设我有一个记录用户活动的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)

问题是,这个查询基本上为每个活动提供了一个单独的行 - 很多很多行,没有计数。我认为问题在于我正在做日期的方式,因为如果我将查询更改为不选择日期,我会得到一个看起来“大多正确”的表。

有什么想法吗?

1 个答案:

答案 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都是最强大的。