sql - 对新创建的列使用 CASE WHEN
问题描述
我在 SQL Server 中有一个表,我按 ID 对它进行了分组,并创建了 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
期望的输出(如果 >= 4,则代码为 1,否则为 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
解决方案
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 非常擅长不重复不必要的工作,事实上,上面的所有三个查询都产生完全相同的执行计划,具有完全相同的成本、相同的读取次数、相同的输出和完全相同的数量表达式的计算。CPU 和持续时间会略有不同,因为计算机。
如果您遇到 CTE 产生比重复表达式更好的计划的情况(请注意,在某些情况下,两种变体可能会产生多个计数表达式),请将其发布在某处。
推荐阅读
- nginx - Nginx 代理通行证不渲染
- r - 如何根据不同的类找到多少个唯一值
- spring-boot - Spring Cloud Contract:在运行时找不到本地合约生成存根
- java - HQL查询左连接和带有数组的bean
- javascript - Laravel $request->all() 没有返回任何响应 ajax 请求
- javascript - 如何在javascript中加载没有点击事件的函数
- python - 为什么 Pipenv 没有选择我的 Pyenv 版本?
- r - 满足条件时如何添加包含特定值的列?
- c++ - 如何找到丢失的图书馆的位置
- angular - Angular 10 中的 .toPromise() 异常