У меня есть таблица в SQL Server, я сгруппировал ее по идентификатору и создал 2 новых столбца с подсчетом других данных. Я хочу иметь возможность создать еще один столбец одновременно, который отображает 1, если счетчики в обоих столбцах больше числа, в противном случае будет отображаться 2. Однако, когда я пытаюсь это сделать, он говорит недопустимое имя столбца, я думаю, как столбцы моего подсчета отсутствуют в исходной таблице?

Мои данные похожи на:

    ID    Data1    Data2
-------------------------
0    1       1       5
1    1       2       5
2    1       5       8
3    1       7       9
4    2       8       5
5    2       7       3
6    2       9       2
7    3       3       1
8    3       3       6
9    3       2       7
10   3       6       3
11   3       8       0

Желаемый результат (где код равен 1, если> = 4, иначе 2):

   ID  CountData1  CountData2  Code
------------------------------------
0   1           4           4     1
1   2           3           3     2
2   3           5           5     1

Текущий запрос:

SELECT 
    ID,
    COUNT(Data1) AS CountData1,
    COUNT(Data2) AS CountData2,
    (CASE WHEN (CountData1 >= 4 and CountData2 >= 4) THEN 1 ELSE 2 END) AS Code
FROM 
    Table
GROUP BY 
    ID
1
Emi OB 11 Окт 2021 в 10:44

2 ответа

Лучший ответ

При синтаксическом анализе операторов SQL нельзя ссылаться на выражение, которое вы только что создали в той же области.

Вы можете повторить выражения еще раз:

SELECT 
    ID,
    COUNT(Data1) AS CountData1,
    COUNT(Data2) AS CountData2,
    (CASE WHEN (COUNT(Data1) >= 4 and COUNT(Data2) >= 4) THEN 1 ELSE 2 END) 
    AS Code
FROM 
    dbo.Table
GROUP BY 
    ID;

Или используйте CTE или производную таблицу:

-- CTE

;WITH cte AS 
(
  SELECT ID, 
      COUNT(Data1) AS CountData1,
      COUNT(Data2) AS CountData2
    FROM dbo.Table 
    GROUP BY ID
)
SELECT ID, CountData1, CountData2,
  CASE WHEN CountData1 >= 4 AND CountData2 >- 4 
    THEN 1 ELSE 2 END AS Code
FROM cte;

-- Derived Table

SELECT ID, CountData1, CountData2,
  CASE WHEN CountData1 >= 4 AND CountData2 >- 4 
    THEN 1 ELSE 2 END AS Code
FROM     
(
  SELECT ID, 
      COUNT(Data1) AS CountData1,
      COUNT(Data2) AS CountData2
    FROM dbo.Table 
    GROUP BY ID
) AS DerivedTable;

Все они работают одинаково, несмотря на то, что некоторые люди считают, что первый хуже, потому что вы ссылаетесь на COUNT() больше раз. SQL Server довольно хорош в том, что не повторяет работу, которую ему не нужно, и на самом деле все три вышеуказанных запроса дают один и тот же план выполнения с точно такой же стоимостью, одинаковым количеством чтений, одним и тем же выводом и точно таким же числом. выражений вычислены. Процессор и продолжительность будут немного отличаться, потому что, ну, компьютеры.

все три плана одинаковы

Если у вас есть случай, когда CTE дает лучший план, чем повторение выражений (учитывая, что в некоторых случаях оба варианта приведут к нескольким выражениям подсчета), опубликуйте это где-то.

3
Aaron Bertrand 11 Окт 2021 в 08:10
SELECT TT.ID,TT.CountData1,TT.CountData2,
CASE WHEN TT.CountData1>= 4 and TT.CountData2>=4 THEN 1 ELSE 2 END CODE
FROM
(SELECT ID,
COUNT(Data1) AS CountData1,
COUNT(Data2) AS CountData2
FROM 
   Table
GROUP BY 
 ID)TT;
0
moin 11 Окт 2021 в 08:03