检查列中的所有值是不是都属于特定组

Posted

技术标签:

【中文标题】检查列中的所有值是不是都属于特定组【英文标题】:Check if all values in a column falls into a specific group检查列中的所有值是否都属于特定组 【发布时间】:2021-04-26 14:09:53 【问题描述】:

我有下表:

+-------+
| Token |
+=======+
| A     |
+-------+
| B     |
+-------+
| B     |
+-------+
| C     |
+-------+
| A     |
+-------+
| X     |
+-------+

我想检查“令牌”列的所有值并返回一个标志字符串来指定满足什么条件:

当所有记录都在组(A,B)中时-->返回'Condition1'

例子:

AABAAB: true
AAAAAA: false
BBBBBB: false
AABBAC: false
当所有记录都在组(A,B,C)中时-->返回'Condition2'

例子:

AABBAC: true
AABAAB: false
AAAAAA: false
BBBBBB: false
AXBBAC: false

所以我基本上是在寻找一个一般的 SELECT 语句,如下所示:

      select case when exists ( select ....
                                  from test_table
                                 where  ....)  -- the SQL Statement that checks if Condition1 is met
                  then 'Condition1'
                  when exists ( select ....
                                  from test_table
                                 where ....) -- the SQL Statement that checks if Condition1 is met
                  then 'Condition1'
                  else 'NOTHING'
             end condition_met
        from dual;

或提供所需结果的任何其他形式的 SQL。

【问题讨论】:

【参考方案1】:

您可以使用LISTAGG() 聚合函数以逗号分隔列表的形式获取Token 的所有不同值,并在CASE 表达式中检查结果:

WITH cte AS (
  SELECT LISTAGG(Token, ',') WITHIN GROUP (ORDER BY Token) Tokens
  FROM (SELECT DISTINCT Token FROM tablename) t
)
SELECT CASE Tokens
  WHEN 'A,B' THEN 'Condition1'
  WHEN 'A,B,C' THEN 'Condition2'
  ELSE 'Nothing'
END condition_met  
FROM cte

请参阅demo。

请注意,在最新版本的 Oracle 中,您可以在 LISTAGG() 中包含 DISTINCT

WITH cte AS (
  SELECT LISTAGG(DISTINCT Token, ',') WITHIN GROUP (ORDER BY Token) Tokens
  FROM tablename
)
....................................

【讨论】:

【参考方案2】:

我只会使用case 表达式:

select (case when sum(case when token = 'A' then 1 else 0 end) > 0 and
                  sum(case when token = 'B' then 1 else 0 end) > 0 and
                  sum(case when token = 'C' then 1 else 0 end) > 0 and
                  sum(case when token not in ('A', 'B', 'C') then 1 else 0 end) = 0
             then 'Condition ABC'
             when sum(case when token = 'A' then 1 else 0 end) > 0 and
                  sum(case when token = 'B' then 2 else 0 end) > 0 and
                  sum(case when token not in ('A', 'B') then 1 else 0 end) = 0
             then 'Condition AB'
        end)
from test_table

【讨论】:

谢谢,但是当有外来字符时它会失败,例如:AABABX -> 它返回“条件 AB”,而它应该返回 null。这同样适用于 ABCABX --> 在预期为 null 时返回“条件 AABC”。 @EzzedeenSaghier 。 . .这很容易通过添加附加条件来解决。【参考方案3】:

尝试计算 A、B 和 C 的数量:

SELECT CASE WHEN Total = A + B -- Optional: AND A > 0 AND B > 0
            THEN 'Condition1'
            WHEN Total = A + B + C -- Optional: AND A > 0 AND B > 0 AND C > 0
            THEN 'Condition2'
            ELSE 'NOTHING'
       END AS Result
  FROM ( SELECT SUM(CASE Token WHEN 'A' THEN 1 ELSE 0 END) AS A
              , SUM(CASE Token WHEN 'B' THEN 1 ELSE 0 END) AS B
              , SUM(CASE Token WHEN 'C' THEN 1 ELSE 0 END) AS C
              , COUNT(*) AS Total
           FROM test_table ) X

【讨论】:

以上是关于检查列中的所有值是不是都属于特定组的主要内容,如果未能解决你的问题,请参考以下文章

检查数据框列中的所有值是不是相同

如何检查numpy矩阵的列中的所有值是不是相同?

如何检查用户是不是在 LDAP 组中

如何编写 R 脚本来检查直线;即,对于任何给定的行,一组列中的所有值是不是具有相同的值

检查VBA中的列中是不是存在值

TSQL查找组中的所有记录是不是具有相同的值