我已经研究了这一点,但我无法找到我遇到的问题的答案。我有一个有四列的表,如下所示:
+------+------+------+------+
|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 |
+------+------+------+------+
因此,为了扩展结果,我们可以查看加载C并看到它出现多次,但加载C,停止1只出现一次。加载C,停止1仅在A / D / AD列中具有值D,因此返回。我尝试了多个涉及case语句的解决方案,但这似乎并不是我需要的。我已经考虑过使用工会本身,但我无法做到这一点,因为它们可能会返回不同数量的行。我完全坚持如何实现必要的逻辑来实现我的目标。任何帮助将不胜感激
答案 0 :(得分:0)
有很多方法。自然或简单的方法是使用子查询检查存在(在您的情况下匹配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
对的行Load/Stop
对的行。然后,您可以使用简单的计数查询轻松找到要返回的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