Chciałbym wyświetlić kolumnę B
w moim poniższym SQL, ale kiedy dodam ją do zapytania, otrzymuję następujący błąd:
Kolumna T2.B 'jest nieprawidłowa na liście wyboru, ponieważ nie jest zawarta ani w funkcji agregującej, ani w klauzuli GROUP BY.
Mój kod:
SELECT A, COUNT(B) as T1, B
FROM T2
WHERE ID=1
GROUP BY A
sql-server
group-by
msvuze
źródło
źródło
Odpowiedzi:
Innymi słowy, ten błąd mówi ci, że SQL Server nie wie, który
B
wybrać z grupy.Albo chcesz wybrać jedną konkretną wartość (np.
MIN
,SUM
LubAVG
), w którym to przypadku użyjesz odpowiedniej funkcji agregującej, albo chcesz wybrać każdą wartość jako nowy wiersz (tj. UwzględniaćB
naGROUP BY
liście pól).Weź pod uwagę następujące dane:
Zapytanie
SELECT A, COUNT(B) AS T1 FROM T2 GROUP BY A
zwróci:
co jest dobre i dobre.
Jednak weź pod uwagę następujące (niedozwolone) zapytanie, które spowodowałoby ten błąd:
SELECT A, COUNT(B) AS T1, B FROM T2 GROUP BY A
I zwrócony zestaw danych ilustrujący problem:
Jednak poniższe dwa zapytania wyjaśniają to jasno i nie spowodują błędu:
Korzystanie z agregatu
SELECT A, COUNT(B) AS T1, SUM(B) AS B FROM T2 GROUP BY A
zwróci:
Dodanie kolumny do
GROUP BY
listySELECT A, COUNT(B) AS T1, B FROM T2 GROUP BY A, B
zwróci:
źródło
Konsekwencją tego jest to, że możesz potrzebować raczej szalenie wyglądającego zapytania, np.
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]
Ponieważ tabela podstawowa jest tabelą podsumowań, jej klucz podstawowy obsługuje jedyne grupowanie lub porządkowanie, które jest naprawdę konieczne. W związku z tym klauzula GROUP BY istnieje wyłącznie w celu zaspokojenia parsera zapytań.
źródło
Możesz użyć przypadku w aktualizacji i zamienić tyle, ile chcesz
update Table SET column=(case when is_row_1 then value_2 else value_1 end) where rule_to_match_swap_columns
źródło