【问题标题】:How to select rows from table when a column repeats?当列重复时如何从表中选择行?
【发布时间】:2022-01-16 22:07:07
【问题描述】:

我有这张表 (REGIONS) 和这个样本值:

Id Cod1 Cod2 Payed
1 0001 000A NULL
2 0001 000B YES
3 0001 000B YES
4 0001 000C NULL
5 0001 000C YELL
6 0001 000D NULL
7 0002 000A YES
8 0002 000C NULL
9 0002 000C NULL
10 0002 000C YES
11 0003 000C YES
12 0004 000C YES
13 0005 000A NULL
14 0005 000A YES
15 0005 000A NULL

我需要一个返回这个的选择:

Cod1 Cod2 NumNullPayed NumYESPayed
0001 000A 1 0
0001 000B 0 2
0001 000C 1 1
0001 000D 1 0
0002 000A 0 1
0002 000C 2 1

我需要按 Cod1 和 Cod2 分组(并计算在 null 或 yes 时支付)。但只有当我们有一个 Cod1 乘以 Cod2 的值时。

在前面的示例中,表有 6 个值/行,Cod1 = 0001;对于 Cod1= 0001,我们有 4 个 Cod2 值(A、B、C、D)。

与 cod1 = 0002 相同。但对于 Cod1 = 0003,Cod2 只有一个值 (000C),与 0004 (000C) 相同。

对于 Cod1 = 0005,我们有三行,但总是使用相同的 Cod2 (000A)。所以在选择中,cod1 = 0003, 0004 和 0005 必须排除,因为它们总是有相同的 Cod2。

见第二张表。

【问题讨论】:

  • 这称为条件聚合。快速搜索将为您提供丰富的解决方案。
  • 我知道是条件聚合,但是想不出怎么按照我老板想要的方式去做
  • 如果你的老板不喜欢链接副本中的操作方式,请与你的老板谈谈,因为他们似乎给了你任意要求(我们不知道这些任意要求是什么) .
  • 您重定向的论坛使用第三列(优先)作为总和。在我的情况下,这将有助于支付总和。但我不知道如何使用 Cod1 和 Cod2 进行分组,并查看它们是否与不同的 cod2 重复 cod1。我需要一些帮助才能在 select clausure 和 group by clausure 中使用这些列。
  • "但是我不知道如何使用 Cod1 和 Cod2 进行分组" GROUP BY Cod1, Cod2...

标签: sql sql-server select group-by count


【解决方案1】:

首先过滤到具有Cod2 唯一值的行(我使用MIN/MAX,因为您不能执行窗口化COUNT(DISTINCT...))然后聚合:

WITH CTE AS(
    SELECT V.Cod1,
           V.Cod2,
           Payed, WHEN MIN(Cod2) OVER (PARTITION BY Cod1) = MAX(Cod2) OVER (PARTITION BY Cod1) THEN 0 ELSE 1 END AS C
    FROM (VALUES(1    ,'0001','000A',NULL),
                (2    ,'0001','000B','YES'),
                (3    ,'0001','000B','YES'),
                (4    ,'0001','000C',NULL),
                (5    ,'0001','000C','YELL'),
                (6    ,'0001','000D',NULL),
                (7    ,'0002','000A','YES'),
                (8    ,'0002','000C',NULL),
                (9    ,'0002','000C',NULL),
                (10   ,'0002','000C','YES'),
                (11   ,'0003','000C','YES'),
                (12   ,'0004','000C','YES'),
                (13   ,'0005','000A',NULL),
                (14   ,'0005','000A','YES'),
                (15   ,'0005','000A',NULL))V(Id,Cod1,Cod2,Payed))
SELECT Cod1,
       Cod2,
       COUNT(CASE Payed WHEN 'Yes' THEN 1 END) AS Payed,
       COUNT(CASE WHEN Payed IS NULL THEN 1 END) AS NotPayed
FROM CTE C
WHERE c = 1
GROUP BY Cod1,
         Cod2;

db<>fiddle

【讨论】:

  • 它不起作用,它返回 9 行(而不是问题中的 6 行),其中 cod1 = 0003、0004 和 0005
  • 在我的粘贴中遗漏了 WHERE 谓词,抱歉,@Keras-JOB。
  • 感谢我的朋友,它有效!如果你能解释一下查询xD,我会徘徊。为什么要使用 WITH CTE AS( 和这部分:“WHEN MIN(Cod2) OVER (PARTITION BY Cod1) = MAX(Cod2) OVER (PARTITION BY Cod1) THEN 0 ELSE 1 END AS C”到底是做什么的?什么意思WHERE c = 1?对不起,如果这是愚蠢的问题
  • 从答案中,@Keras-JOB “首先过滤到 Cod2 具有一个不同值的行(我使用 MIN/MAX,因为您不能执行窗口计数(DISTINCT.. .)) " 如果MINMAX 相同,则它们具有1 值。
猜你喜欢
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 2015-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多