SQL COUNT DISTINCT with CASE:如何在不使用 exists 的情况下进行子查询?

SQL COUNT DISTINCT with CASE : How do i subquery without using exists?

上下文: 在 SQL 服务器中有一个很大的 XLSX 文件,我正在将其映射到 XML 文件。名为 'referentie' 的列每次都获得不同的值。我需要计算唯一值并相应地显示代码。 (请注意,这是一个更大的 SELECT 语句中的子查询。我无法添加额外的聚合函数。)

  1. 我需要计算 JSON 数组输入的唯一值(输出在 XML 中)。 (完成)
  2. 根据检索到的唯一计数显示值(问题)

问题: 在查询中,您会看到我有多个 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

db<>fiddle

顺便说一句,如果您真的想要子查询中的多个列,则需要将其放在 APPLY.