web-dev-qa-db-fra.com

SQL Server - Colonne "non valide dans la liste de sélection car elle ne figure ni dans une fonction d'agrégat ni dans la clause GROUP BY"

Je voudrais afficher la colonne B dans le code SQL ci-dessous, mais lorsque je l'ajoute à la requête, l'erreur suivante s'affiche:

Colonne T2.B ' n'est pas valide dans la liste de sélection car il ne figure dans aucun fichier fonction d'agrégat ou la clause GROUP BY.

Mon code:

SELECT A, COUNT(B) as T1, B 
FROM T2 
WHERE ID=1 
GROUP BY A 
61
msvuze

En d'autres termes, cette erreur vous indique que SQL Server ne sait pas lequel B choisir dans le groupe. 

Soit vous voulez sélectionner une valeur spécifique (par exemple, MIN, SUM ou AVG), auquel cas vous utiliseriez la fonction d'agrégat appropriée, ou vous souhaitez sélectionner chaque valeur comme une nouvelle ligne (c'est-à-dire inclure B dans la liste de champs GROUP BY) .


Considérez les données suivantes:

 ID A B 
 1 1 13 
 1 1 79 
 1 2 13 
 1 2 13 
 1 2 42 

La requête

SELECT A, COUNT(B) AS T1 
FROM T2 
GROUP BY A

retournerais:

 A T1 
 1 2 
 2 3 

ce qui est bien beau. 

Cependant, considérons la requête suivante (illégale), qui produirait cette erreur:

SELECT A, COUNT(B) AS T1, B 
FROM T2 
GROUP BY A

Et son ensemble de données renvoyé illustrant le problème:

 A T1 B 
 1 2 13? 79? 13 et 79 en tant que lignes séparées? (13 + 79 = 92)? ...? 
 2 3 13? 42? ...? 

Cependant, les deux requêtes suivantes le clarifient et ne causeront pas l'erreur:

  1. Utiliser un agrégat

    SELECT A, COUNT(B) AS T1, SUM(B) AS B
    FROM T2
    GROUP BY A
    

    retournerais:

     A T1 B 
     1 2 92 
     2 3 68 
    
  2. Ajout de la colonne à la liste GROUP BY

    SELECT A, COUNT(B) AS T1, B
    FROM T2
    GROUP BY A, B
    

    retournerais:

     A T1 B 
     1 1 13 
     1 1 79 
     2 2 13 
     2 1 42 
    
111
lc.

Vous pouvez utiliser le cas dans update et SWAP autant que vous le souhaitez

update Table SET column=(case when is_row_1 then value_2 else value_1 end) where rule_to_match_swap_columns
0

La conséquence de ceci est que vous pouvez avoir besoin d'une requête plutôt folle, e. g., 

SELECT [dbo].[tblTimeSheetExportFiles].[lngRecordID]            AS lngRecordID
          ,[dbo].[tblTimeSheetExportFiles].[vcrSourceWorkbookName]  AS vcrSourceWorkbookName
          ,[dbo].[tblTimeSheetExportFiles].[vcrImportFileName]      AS vcrImportFileName
          ,[dbo].[tblTimeSheetExportFiles].[dtmLastWriteTime]       AS dtmLastWriteTime
          ,[dbo].[tblTimeSheetExportFiles].[lngNRecords]            AS lngNRecords
          ,[dbo].[tblTimeSheetExportFiles].[lngSizeOnDisk]          AS lngSizeOnDisk
          ,[dbo].[tblTimeSheetExportFiles].[lngLastIdentity]        AS lngLastIdentity
          ,[dbo].[tblTimeSheetExportFiles].[dtmImportCompletedTime] AS dtmImportCompletedTime
          ,MIN ( [tblTimeRecords].[dtmActivity_Date] )              AS dtmPeriodFirstWorkDate
          ,MAX ( [tblTimeRecords].[dtmActivity_Date] )              AS dtmPeriodLastWorkDate
          ,SUM ( [tblTimeRecords].[decMan_Hours_Actual] )           AS decHoursWorked
          ,SUM ( [tblTimeRecords].[decAdjusted_Hours] )             AS decHoursBilled
      FROM [dbo].[tblTimeSheetExportFiles]
      LEFT JOIN   [dbo].[tblTimeRecords]
              ON  [dbo].[tblTimeSheetExportFiles].[lngRecordID] = [dbo].[tblTimeRecords].[lngTimeSheetExportFile]
        GROUP BY  [dbo].[tblTimeSheetExportFiles].[lngRecordID]
                 ,[dbo].[tblTimeSheetExportFiles].[vcrSourceWorkbookName]
                 ,[dbo].[tblTimeSheetExportFiles].[vcrImportFileName]
                 ,[dbo].[tblTimeSheetExportFiles].[dtmLastWriteTime]
                 ,[dbo].[tblTimeSheetExportFiles].[lngNRecords]
                 ,[dbo].[tblTimeSheetExportFiles].[lngSizeOnDisk]
                 ,[dbo].[tblTimeSheetExportFiles].[lngLastIdentity]
                 ,[dbo].[tblTimeSheetExportFiles].[dtmImportCompletedTime]

Comme la table primaire est une table récapitulative, sa clé primaire gère le seul regroupement ou ordre qui soit réellement nécessaire. Par conséquent, la clause GROUP BY existe uniquement pour satisfaire l'analyseur de requête.

0
David A. Gray