SQL查询:每个GROUP BY表达式必须至少包含一个不是外部引用的列

时间:2010-09-24 17:22:17

标签: sql sql-server tsql group-by user-defined-functions

获取此错误: 每个GROUP BY表达式必须至少包含一个不是外部引用的列。

RowId   ErrorDatetime             ErrorNum         ErrorMessage 
824 2010-09-24 08:01:42.000   9001       Account 55 not found
823 2010-09-24 08:00:56.000   9001      Account 22222222222 not found
822 2010-09-24 05:06:27.000   9001      Account 55 not found
821 2010-09-24 05:05:42.000   9001      Account 22222222222 not found

我正在尝试获取错误消息,并且它是第一次发生在当天,这是有效的,因为我只是做“Group by ErrorMessage”。

但是,如果我想找到每天的第一个:

SELECT Min(ErrorDateTime) as 'ErrorDateTime', Min(ErrorMessage) as 'ErrorMessage'
FROM CommonError 
WHERE dbo.StripTimeFromDate(ErrorDateTime) = dbo.StripTimeFromDate(getdate()) 
     and ErrorNumber = '9001' 
GROUP BY dbo.StripTimeFromDate(getdate()), ErrorMessage 

方便的花花公子功能(来自http://bloggingabout.net/blogs/jschreuder/archive/2007/03/13/useful-t-sql-date-functions.aspx):

ALTER FUNCTION [dbo].[StripTimeFromDate] (@inputDate DATETIME)
RETURNS DATETIME
BEGIN
    RETURN DATEADD(d, DATEDIFF(d, 0, @inputDate), 0)
END

3 个答案:

答案 0 :(得分:2)

首先,您不需要SELECT中的MIN(ErrorMessage)。只需选择ErrorMessage即可。第二,仅限GROUP BY ErrorMessage。

SELECT Min(ErrorDateTime) as 'ErrorDateTime', ErrorMessage
FROM CommonError 
WHERE dbo.StripTimeFromDate(ErrorDateTime) = dbo.StripTimeFromDate(getdate()) 
     and ErrorNumber = '9001' 
GROUP BY ErrorMessage 

答案 1 :(得分:2)

使用:

  SELECT t.errormessage, MIN(t.errordatetime) AS dt
    FROM COMMONERROR t
GROUP BY t.errormessage, DATEADD(d, DATEDIFF(d, 0, t.errordatetime), 0)

检查GROUP BY中的引用;它没有被捕获,因为MIN被应用于同一列。

假设SQL Server 2005+,使用分析更容易处理:

WITH base AS (
   SELECT t.*,
          ROW_NUMBER() OVER(PARTITION BY t.errormessage, DATEADD(d, DATEDIFF(d, 0, t.errordatetime), 0)
                                ORDER BY t.errordatetime) AS rk
     FROM dbo.COMMONERROR t)
SELECT b.*
  FROM base b
 WHERE b.rk = 1
   AND b.errornumber = '9001' 
   AND DATEADD(d, DATEDIFF(d, 0, b.errordatetime), 0) = DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0)

答案 2 :(得分:2)

我在“group by”中使用了getdate()而不是ErrorDate。 我想我在其他论坛上看到了类似的问题,人们在“分组”中有文字。

更正是:

GROUP BY dbo.StripTimeFromDate(ErrorDate), ErrorMessage