Spalte "ungültig in der Auswahlliste, da sie weder in einer Aggregatfunktion noch in der GROUP BY-Klausel enthalten ist"

83

Ich möchte die Spalte Bin meinem folgenden SQL anzeigen , aber wenn ich sie der Abfrage hinzufüge, wird folgende Fehlermeldung angezeigt :

Die Spalte T2.B 'ist in der Auswahlliste ungültig, da sie weder in einer Aggregatfunktion noch in der GROUP BY-Klausel enthalten ist.

Mein Code:

SELECT A, COUNT(B) as T1, B 
FROM T2 
WHERE ID=1 
GROUP BY A 
msvuze
quelle
2
Mögliches Duplikat der Group By-Klausel, das einen Fehler verursacht . Wenn Sie hier in Ihrer Fehlermeldung gesucht haben, finden Sie hier viele Übereinstimmungen, die dies für Sie beantwortet hätten. Bitte geben Sie sich zumindest die Mühe, dies zu tun und die Fehlermeldung tatsächlich zu lesen , die nicht nur das genaue Problem beschreibt, sondern Ihnen auch genau sagt, welche Spalte es verursacht.
Ken White
Mögliches Duplikat von Grund für Spalte ist in der
Auswahlliste

Antworten:

150

Mit anderen Worten, dieser Fehler weist darauf hin, dass SQL Server nicht weiß, welche B aus der Gruppe ausgewählt werden soll.

Entweder Sie wollen einen bestimmten Wert wählen (zB MIN, SUModer AVG) , in dem Fall , dass Sie die entsprechende Aggregatfunktion verwenden, oder Sie wollen jeden Wert als neue Zeile wählen (dh einschließlich Bin der GROUP BYFeldliste).


Betrachten Sie die folgenden Daten:

ID AB
1 1 13
1 1 79
1 2 13
1 2 13
1 2 42

Die Abfrage

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

würde zurückkehren:

UM 1
1 2
2 3

Das ist alles schön und gut.

Beachten Sie jedoch die folgende (unzulässige) Abfrage, die diesen Fehler verursachen würde:

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

Und der zurückgegebene Datensatz veranschaulicht das Problem:

A T1 B.
1 2 13? 79? Sowohl 13 als auch 79 als separate Zeilen? (13 + 79 = 92)? ...?
2 3 13? 42? ...?

Die folgenden zwei Abfragen machen dies jedoch deutlich und verursachen den Fehler nicht:

  1. Verwenden eines Aggregats

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

    würde zurückkehren:

    A T1 B.
    1 2 92
    2 3 68
    
  2. Hinzufügen der Spalte zur GROUP BYListe

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

    würde zurückkehren:

    A T1 B.
    1 1 13
    1 1 79
    2 2 13
    2 1 42
    
lc.
quelle
3
Vielen Dank für diese ausführliche Erklärung - habe einige meiner Fragen wirklich gelöst. Der schwierige Teil mit dem anfänglichen Problem ist, dass Sie die Abfrage für einen optimalen Datensatz ausführen können und diese Ausnahme nicht erhalten. Wenn Sie jedoch doppelte Daten für B haben, erhalten Sie diese Ausnahme. Planen Sie Ihre Anfrage also besser mit den Beispielen, die lc. gab im Voraus :)
qgicup
Was für eine schöne Antwort!
Aerin
0

Die Folge davon ist, dass Sie möglicherweise eine ziemlich verrückt aussehende Abfrage benötigen, z.

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]

Da die Primärtabelle eine Übersichtstabelle ist, behandelt ihr Primärschlüssel die einzige Gruppierung oder Reihenfolge, die wirklich notwendig ist. Daher existiert die GROUP BY-Klausel nur, um den Abfrageparser zu erfüllen.

David A. Gray
quelle
0

Sie können case in update und SWAP so viele verwenden, wie Sie möchten

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