2010-09-24 25 views
0

Obtention de cette erreur: Chaque expression GROUP BY doit contenir au moins une colonne qui n'est pas une référence externe.Requête SQL: Chaque expression GROUP BY doit contenir au moins une colonne qui n'est pas une référence externe

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 

Je suis en train d'obtenir le errormessage, et la première fois qu'il a eu lieu pour la journée en cours, et qui fonctionne parce que je viens de faire « Groupe par ErrorMessage ».

Cependant, si je veux trouver le premier pour chaque jour:

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 

La fonction pratique-dandy (de 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 
+0

Quelle version de SQL Server utilisez-vous? –

Répondre

2

j'avais getdate() au lieu de ErrorDate dans le "groupe par". Je pense avoir vu des problèmes similaires dans d'autres forums où les gens avaient un sens littéral dans le "groupe par".

correction est:

GROUP BY dbo.StripTimeFromDate(ErrorDate), ErrorMessage 
2

D'abord, vous n'avez pas besoin du MIN (ErrorMessage) dans votre SELECT. Il suffit de sélectionner ErrorMessage. Deuxièmement, GROUP BY ErrorMessage uniquement.

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

Je pensais avoir dit que ça fonctionnait, mais ensuite j'ai dit "Cependant, si je veux trouver le premier pour chaque jour" ... – NealWalters

+0

J'ai mal compris les exigences alors. +1 à [OMG Ponies answer] (http://stackoverflow.com/questions/3789487/sql-query-each-group-by-expression-must-contain-at-least-one-column-that-is-not/3789593 # 3789593) dans ce cas. –

+0

Je vois le problème maintenant, j'ai eu getdate() au lieu de ErrorDate dans le groupe par. – NealWalters

2

Utilisation:

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

Vérifiez les références dans le GROUP BY; il ne se faisait pas attraper parce que MIN était appliqué à la même colonne.

En supposant SQL Server 2005+, cela est plus facile à manipuler avec l'analyse:

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) 
+0

Fonctionne bien (même lorsque je sors le test pour la date du jour). Cependant, je dois admettre que j'ai suffisamment étudié l'analytique pour le comprendre. J'espérais rester avec ma requête simple et juste me débarrasser de l'erreur. Je ne sais pas pourquoi il se réfère à "référence externe". – NealWalters