Столбец «недопустим в списке выбора, потому что он не содержится ни в агрегатной функции, ни в предложении GROUP BY»

84

Я хотел бы отобразить столбец Bв моем нижеприведенном SQL, но когда я добавляю его в запрос, он дает мне следующую ошибку:

Столбец T2.B 'недопустим в списке выбора, поскольку он не содержится ни в агрегатной функции, ни в предложении GROUP BY.

Мой код:

SELECT A, COUNT(B) as T1, B 
FROM T2 
WHERE ID=1 
GROUP BY A 
мсвузе
источник
2
возможный дубликат предложения Group By, вызывающий ошибку . Если бы вы искали здесь свое сообщение об ошибке, вы бы нашли здесь много совпадений, которые ответили бы на это за вас. Пожалуйста, по крайней мере приложите усилия для этого, а также для фактического чтения сообщения об ошибке, которое не только описывает точную проблему, но и сообщает вам, какой именно столбец вызывает ее.
Ken White

Ответы:

153

Другими словами, эта ошибка сообщает вам, что SQL Server не знает, что B выбрать из группы.

Либо вы хотите выбрать одно значение конкретное (например MIN, SUMили AVG) , в этом случае вы должны использовать соответствующую статистическую функцию, или вы хотите , чтобы выбрать все значения в качестве новой строки (т.е. в том числе Bв GROUP BYсписке полей).


Рассмотрим следующие данные:

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

Запрос

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

вернется:

А Т1
1 2
2 3

что все хорошо.

Однако рассмотрим следующий (недопустимый) запрос, который приведет к этой ошибке:

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

И возвращенный набор данных, иллюстрирующий проблему:

А Т1 Б
1 2 13? 79? И 13, и 79 как отдельные строки? (13 + 79 = 92)? ...?
2 3 13? 42? ...?

Однако следующие два запроса проясняют это и не вызывают ошибки:

  1. Использование агрегата

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

    вернется:

    А Т1 Б
    1 2 92
    2 3 68
    
  2. Добавление столбца в GROUP BYсписок

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

    вернется:

    А Т1 Б
    1 1 13
    1 1 79
    2 2 13
    2 1 42
    
lc.
источник
3
спасибо за это подробное объяснение - действительно решил некоторые из моих вопросов. сложность первоначальной проблемы заключается в том, что вы можете выполнить запрос на некотором оптимальном наборе данных, и вы не получите этого исключения. но когда у вас есть повторяющиеся данные для B, вы получите это исключение. Так что лучше спланируйте свой запрос с примерами, которые lc. дал аванс :)
qgicup
какой хороший ответ !!
Aerin
0

Следствием этого является то, что вам может потребоваться довольно безумный запрос, например,

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]

Поскольку основная таблица является сводной таблицей, ее первичный ключ обрабатывает единственную действительно необходимую группировку или упорядочение. Следовательно, предложение GROUP BY существует исключительно для удовлетворения запросов синтаксического анализатора.

Дэвид А. Грей
источник
0

Вы можете использовать case в обновлении и SWAP сколько угодно

update Table SET column=(case when is_row_1 then value_2 else value_1 end) where rule_to_match_swap_columns
Вишванат Лекшманан
источник