SQL COUNT DISTINCT with CASE:如何在不使用 exists 的情况下进行子查询?
SQL COUNT DISTINCT with CASE : How do i subquery without using exists?
上下文:
在 SQL 服务器中有一个很大的 XLSX 文件,我正在将其映射到 XML 文件。名为 'referentie' 的列每次都获得不同的值。我需要计算唯一值并相应地显示代码。 (请注意,这是一个更大的 SELECT 语句中的子查询。我无法添加额外的聚合函数。)
- 我需要计算 JSON 数组输入的唯一值(输出在 XML 中)。 (完成)
- 根据检索到的唯一计数显示值(问题)
问题:
在查询中,您会看到我有多个 COUNT DISTINCT CASES。 SQL 抛出正常的错误:
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
我的查询:
(SELECT COUNT(DISTINCT CASE WHEN Referentie > 10 THEN N'CON1' END) AS [HEADER/CHECK],
COUNT(DISTINCT CASE WHEN Referentie <= 10 AND Referentie > 29 THEN N'CON2' END) AS [HEADER/CHECK],
COUNT(DISTINCT CASE WHEN Referentie <= 30 AND Referentie >= 50 THEN N'CON3' END) AS [HEADER/CHECK],
COUNT(DISTINCT CASE WHEN Referentie <= 50 AND Referentie >= 500 THEN N'CON4' END) AS [HEADER/CHECK]
FROM OPENJSON(@Json, N'$.Blad1')
WITH (Referentie nvarchar(100) N'$.Referentie')) AS [HEADER/CHECK],
问题:
- 使我的逻辑起作用的正确语法是什么?
JSON 在文件中:
@Json = N'{
"Blad1":[
{
removed
}
]
}'
我已将第一个查询放在 CTE 中,然后将您的条件放在后面的查询中,但结果可能不是您所期望的。首先 Referentie 是 alpha-numerique 所以我刚刚使用了数字部分,其次只有一个你正在测试的值被满足。
因此,我按 Referntie 分组并显示了重复项的数量,以便在您优化查询时使事情变得更清楚。
declare @json varchar(max);
set @Json = ---- THE VALUE GIVEN IN THE QUESTION ---
WITH myJson as (
select
right(Referentie,7) Referentie
FROM OPENJSON(@Json, N'$.Blad1')
WITH (Referentie nvarchar(100) ) AS [HEADER/CHECK]
)
SELECT
COUNT(*) "number",
Referentie,
COUNT(DISTINCT CASE WHEN Referentie > 10 THEN N'CON1' END) AS [HEADER/CHECK],
COUNT(DISTINCT CASE WHEN Referentie <= 10 AND Referentie > 29 THEN N'CON2' END) AS [HEADER/CHECK],
COUNT(DISTINCT CASE WHEN Referentie <= 30 AND Referentie >= 50 THEN N'CON3' END) AS [HEADER/CHECK],
COUNT(DISTINCT CASE WHEN Referentie <= 50 AND Referentie >= 500 THEN N'CON4' END) AS [HEADER/CHECK]
FROM myJson
GROUP BY Referentie
GO
number | Referentie | HEADER/CHECK | HEADER/CHECK | HEADER/CHECK | HEADER/CHECK
-----: | :--------- | -----------: | -----------: | -----------: | -----------:
1 | 2348657 | 1 | 0 | 0 | 0
10 | 4221860 | 1 | 0 | 0 | 0
1 | 6969860 | 1 | 0 | 0 | 0
db<>fiddle here
首先,您不太清楚自己想要达到的目标。你说你正在设法计算唯一值,但不显示依赖于该值的值。
您的代码甚至无法做到这一点。它实际上做的是检查 Referentie
是否在定义的数字内(这没有意义,因为它是一个字符串),然后在单个字符串上区分。然后它returns多次,每个参数一次。
相反,您需要一个 single COUNT (DISTINCT Referentie)
,它周围有一个 CASE
检查它是多少。
您当前的代码还有另一个问题。条件 >
和 <
是倒退的。 < 29
应该是 < 30
.
SELECT
'SomeValue' AS xyz,
(
SELECT
CASE
WHEN COUNT(DISTINCT Referentie) < 10
THEN N'CON1'
WHEN COUNT(DISTINCT Referentie) >= 10 AND COUNT(DISTINCT Referentie) < 29
THEN N'CON2'
WHEN COUNT(DISTINCT Referentie) >= 30 AND COUNT(DISTINCT Referentie) <= 50
THEN N'CON3'
WHEN COUNT(DISTINCT Referentie) >= 50 AND COUNT(DISTINCT Referentie) <= 500
THEN N'CON4'
END
FROM OPENJSON(@Json, N'$.Blad1')
WITH (
Referentie nvarchar(100)
) AS j
) AS [HEADER/CHECK]
FROM (VALUES(0)) DummyTable(DummyValue) -- don't know what the rest of your query is
FOR XML PATH(N''), ROOT(N'rootElement'),TYPE
顺便说一句,如果您真的想要子查询中的多个列,则需要将其放在 APPLY
.
中
上下文: 在 SQL 服务器中有一个很大的 XLSX 文件,我正在将其映射到 XML 文件。名为 'referentie' 的列每次都获得不同的值。我需要计算唯一值并相应地显示代码。 (请注意,这是一个更大的 SELECT 语句中的子查询。我无法添加额外的聚合函数。)
- 我需要计算 JSON 数组输入的唯一值(输出在 XML 中)。 (完成)
- 根据检索到的唯一计数显示值(问题)
问题: 在查询中,您会看到我有多个 COUNT DISTINCT CASES。 SQL 抛出正常的错误:
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
我的查询:
(SELECT COUNT(DISTINCT CASE WHEN Referentie > 10 THEN N'CON1' END) AS [HEADER/CHECK],
COUNT(DISTINCT CASE WHEN Referentie <= 10 AND Referentie > 29 THEN N'CON2' END) AS [HEADER/CHECK],
COUNT(DISTINCT CASE WHEN Referentie <= 30 AND Referentie >= 50 THEN N'CON3' END) AS [HEADER/CHECK],
COUNT(DISTINCT CASE WHEN Referentie <= 50 AND Referentie >= 500 THEN N'CON4' END) AS [HEADER/CHECK]
FROM OPENJSON(@Json, N'$.Blad1')
WITH (Referentie nvarchar(100) N'$.Referentie')) AS [HEADER/CHECK],
问题:
- 使我的逻辑起作用的正确语法是什么?
JSON 在文件中:
@Json = N'{
"Blad1":[
{
removed
}
]
}'
我已将第一个查询放在 CTE 中,然后将您的条件放在后面的查询中,但结果可能不是您所期望的。首先 Referentie 是 alpha-numerique 所以我刚刚使用了数字部分,其次只有一个你正在测试的值被满足。
因此,我按 Referntie 分组并显示了重复项的数量,以便在您优化查询时使事情变得更清楚。
declare @json varchar(max); set @Json = ---- THE VALUE GIVEN IN THE QUESTION ---
WITH myJson as ( select right(Referentie,7) Referentie FROM OPENJSON(@Json, N'$.Blad1') WITH (Referentie nvarchar(100) ) AS [HEADER/CHECK] ) SELECT COUNT(*) "number", Referentie, COUNT(DISTINCT CASE WHEN Referentie > 10 THEN N'CON1' END) AS [HEADER/CHECK], COUNT(DISTINCT CASE WHEN Referentie <= 10 AND Referentie > 29 THEN N'CON2' END) AS [HEADER/CHECK], COUNT(DISTINCT CASE WHEN Referentie <= 30 AND Referentie >= 50 THEN N'CON3' END) AS [HEADER/CHECK], COUNT(DISTINCT CASE WHEN Referentie <= 50 AND Referentie >= 500 THEN N'CON4' END) AS [HEADER/CHECK] FROM myJson GROUP BY Referentie
GO
number | Referentie | HEADER/CHECK | HEADER/CHECK | HEADER/CHECK | HEADER/CHECK -----: | :--------- | -----------: | -----------: | -----------: | -----------: 1 | 2348657 | 1 | 0 | 0 | 0 10 | 4221860 | 1 | 0 | 0 | 0 1 | 6969860 | 1 | 0 | 0 | 0
db<>fiddle here
首先,您不太清楚自己想要达到的目标。你说你正在设法计算唯一值,但不显示依赖于该值的值。
您的代码甚至无法做到这一点。它实际上做的是检查 Referentie
是否在定义的数字内(这没有意义,因为它是一个字符串),然后在单个字符串上区分。然后它returns多次,每个参数一次。
相反,您需要一个 single COUNT (DISTINCT Referentie)
,它周围有一个 CASE
检查它是多少。
您当前的代码还有另一个问题。条件 >
和 <
是倒退的。 < 29
应该是 < 30
.
SELECT
'SomeValue' AS xyz,
(
SELECT
CASE
WHEN COUNT(DISTINCT Referentie) < 10
THEN N'CON1'
WHEN COUNT(DISTINCT Referentie) >= 10 AND COUNT(DISTINCT Referentie) < 29
THEN N'CON2'
WHEN COUNT(DISTINCT Referentie) >= 30 AND COUNT(DISTINCT Referentie) <= 50
THEN N'CON3'
WHEN COUNT(DISTINCT Referentie) >= 50 AND COUNT(DISTINCT Referentie) <= 500
THEN N'CON4'
END
FROM OPENJSON(@Json, N'$.Blad1')
WITH (
Referentie nvarchar(100)
) AS j
) AS [HEADER/CHECK]
FROM (VALUES(0)) DummyTable(DummyValue) -- don't know what the rest of your query is
FOR XML PATH(N''), ROOT(N'rootElement'),TYPE
顺便说一句,如果您真的想要子查询中的多个列,则需要将其放在 APPLY
.