【问题标题】:Select rows with multiple values in columns and compare value in different column选择列中具有多个值的行并比较不同列中的值
【发布时间】:2018-03-31 03:55:43
【问题描述】:

我对此进行了大量研究,但我找不到我遇到的问题的答案。我有一个有四列的表,如下所示:

+------+------+------+------+
|ID    |LOAD  |STOP  |A/D/AD|
+------+------+------+------+
|1     |A     |1     |A     |
+------+------+------+------+
|2     |B     |2     |AD    |
+------+------+------+------+
|3     |C     |1     |D     |
+------+------+------+------+
|4     |A     |1     |D     |
+------+------+------+------+
|5     |D     |2     |AD    |
+------+------+------+------+
|6     |C     |2     |A     |
+------+------+------+------+
|7     |C     |2     |D     |
+------+------+------+------+
|8     |E     |1     |A     |
+------+------+------+------+
|9     |F     |2     |D     |
+------+------+------+------+
|10    |G     |1     |A     |
+------+------+------+------+

据此,我需要检索所有在 A/D/AD 列中没有 AD 或 A 和 D 的加载和停止编号。为了进一步澄清,我想查看每个单独的负载并查看其停止编号,然后查看表中是否还有其他具有这些值的外观。然后我想看看这些值是什么,只有在 A/D/AD 列中没有 AD 或两个同时具有 A 和 D 的条目时才返回条目。所以我的结果应该是这样的:

+------+------+------+------+
|ID    |LOAD  |STOP  |A/D/AD|
+------+------+------+------+
|3     |C     |1     |D     |
+------+------+------+------+
|8     |E     |1     |A     |
+------+------+------+------+
|9     |F     |2     |D     |
+------+------+------+------+
|10    |G     |1     |A     |
+------+------+------+------+

因此,为了扩展结果,我们可以查看 Load C 并看到它出现了多次,但 Load C, Stop 1 只出现了一次。 Load C, Stop 1 仅在 A/D/AD 列中具有 D 值,因此它被返回。我尝试了多种涉及案例陈述的解决方案,但这似乎并不是我所需要的。我已经研究过在其自身上使用联合,但我无法这样做,因为它们可能会返回不同数量的行。我只是完全坚持如何实现必要的逻辑来实现我的目标。任何帮助将不胜感激

【问题讨论】:

    标签: sql database db2


    【解决方案1】:

    有多种方法。自然或简单的方法是使用子查询检查是否存在(在您的情况下,匹配 Load 和 Stop 列)。如果您将整个工作分解成小块,则可以使用UNION 将每个块组合成最终输出。因此,解决您问题的“第一原则”方法是:

    select  Id, Load, Stop, A_D_AD
    from    Table a
    where   A_D_AD = 'A'
        and not exists (
            select  *
            from    Table d
            where   d.Load = a.Load
                and d.Stop = a.Stop
                and d.A_D_AD = 'D'
    union all
    select  ... 
    /* Similar query for rows where A_D_AD = 'D' but 
       matches for A_D_AD = 'A' do not exist.  */
    

    但是,在某些情况下,您可能能够更好地理解输入数据。例如。如果你的情况是这样的:

    • 给定Load/Stop 对的任何“A”行
    • 从不存在“AD”行,
    • 永远不会有第二个“A”行,
    • 并且只有 0 或 1 个“D”行。
    • 对于给定Load/Stop 对的“D”行类似。

    然后您可以使用简单的计数查询轻松找到要返回的 Load/Stop 对:

    select  Load, Stop
    from    Table t
    where   t.A_D_AD in ('A', 'D')
    group by Load, Stop
    having  count(*) = 1 /* Guarantees either A without D or vice-versa*/
    

    将这些结果连接回基表会生成所有列(在下一个示例中演示)。

    最后,在一些更复杂的场景中,您可能会发现更容易:

    • 将您的数据转换为您感兴趣的值的摘要;
    • 根据您的规则过滤;
    • 并加入回源数据

    例如:

    select  Id, Load, Stop, A_D_AD
    from    (
            select  *
            from    (
                    select  Load, Stop,
                            sum(case A_D_AD when 'A' then 1 else 0 end) as A_Count,
                            sum(case A_D_AD when 'D' then 1 else 0 end) as D_Count,
                            sum(case A_D_AD when 'AD' then 1 else 0 end) as AD_Count
                    from    Table
                    group by Load, Stop
                    ) pvt /* Pivoted to count the rows for each A/D/AD value */
    
            where   pvt.AD_Count = 0
                or  (pvt.A_Count = 0 and pvt.D_Count = 0)
            ) f /* The Stop/Load rows to return */
            inner join Table src /* Join back to source data */
              on  src.Stop = f.Stop
              and src.Load = f.Load
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-24
      • 2021-08-09
      • 1970-01-01
      • 2014-12-08
      • 2022-01-09
      • 2020-01-27
      相关资源
      最近更新 更多