代码之家  ›  专栏  ›  技术社区  ›  Mike Saull

SQL聚合表是否包含类别或记录类型

  •  0
  • Mike Saull  · 技术社区  · 1 年前

    有人能想到一种更好的方法来构造这个问题的SQL查询吗?

    我想按account_id分组,并确定表中是否存在某种类型的行,然后将其聚合为一个简单的true/false,以确定该account_id是否存在该类型的行

    TABLE user_account_values
    COLUMNS:
    user_id,
    account_id,
    svc_id,
    card_id,
    name,
    status
    

    Account_id在表中不是唯一的

    例如,结果如下,其中类别由定义的可能值列表确定

    帐户ID,类别1存在,类别2存在

    1. 123,真的,假的
    2. 124,假,真
    3. 125,假的,假的

    我目前的解决方案是根据行是否与类别匹配来创建一种位图,然后用MAX()聚合,如果account_id存在类别,则选择1作为true

    SELECT account_id, 
    MAX(first) as firstExists, 
    MAX(final) as finalExists
    
    FROM
    (SELECT account_id,
    
    CASE WHEN name 
    IN ('something1_first', 'something2_first')
    THEN 1 ELSE 0 END AS first,
    
    CASE WHEN name 
    IN ('something1_final', 'something2_final') 
    THEN 1 ELSE 0 END AS final
    
    FROM user_account_values 
    WHERE user_id = :user and account_id is not null and status = 'A' 
    )
    
    GROUP BY account_id
    

    有没有更简单的方法来实现这一点?

    我还想,也许你可以选择一个account_id,其中每个类别的name都在(*)中,然后在account_id上将它们连接在一起,但似乎性能会更差,我可能需要在最终查询中检查超过4/5个类别。

    1 回复  |  直到 1 年前
        1
  •  1
  •   Paul W    1 年前

    在聚合中组合条件。

    SELECT account_id,
           MAX(CASE WHEN (name IN ('something1_first','something2_first')) THEN 'Y' ELSE 'N' END) firstexists,
           MAX(CASE WHEN (name IN ('something1_final','something2_final')) THEN 'Y' ELSE 'N' END) finalexists
      FROM mytable
     GROUP BY account_id
    

    这之所以有效,是因为 Y 衣领高于 N 所以如果有一个 Y 由此而来 case 函数的整体结果将是 Y 当然,这个主题有很多变化,但这表明了这个概念。

    如果你真的想要字符串 'true' 'false' (你不能有真正的布尔值,至少从19世纪开始是这样)你可以用它们来代替 Y N 因为 true 将评估高于 false 按字母顺序排列。但这不是好的编程,因为这不是不言而喻的。如果你确实想要字符串,不想依赖这两个字符串之间的意外顺序,那么只需翻译 Y / N (或 0 / 1 或任何正确的顺序)转换为您喜欢的字符串:

    SELECT account_id,
           DECODE(MAX(CASE WHEN (name IN ('something1_first','something2_first')) THEN 'Y' ELSE 'N' END),'Y','true','false') firstexists,
           DECODE(MAX(CASE WHEN (name IN ('something1_final','something2_final')) THEN 'Y' ELSE 'N' END),'Y','true','false') finalexists
      FROM mytable
     GROUP BY account_id
    
    推荐文章