【问题标题】:sql multiple filter all conditions in a groupsql 多重过滤组中的所有条件
【发布时间】:2019-02-23 06:51:04
【问题描述】:

我有一个包含 3 个字段的表格:

id       order        date

1        1            null
1        2            not null
1        3            null
2        1            null
2        2            null
2        3            null
2        4            not null
3        1            null

我需要其中的“id”:

  • (1,2,3) 中的所有“顺序”

  • 所有的“日期”都是空的(所以它是 id 2)

我试过如下:

where order in (1,2,3) and date is null

但它同时返回 id 2 和 id 1(我只期望 id 2)。

感谢您的帮助。

【问题讨论】:

  • 你为什么不期待 id 3?它有订单1,在(1,2,3),日期是null
  • Id 2 的 orderid 4 无效,您还想要吗?
  • 对于 SQL 问题,您应该始终标记您的 DBMS。哪个是你的? MySQL? SQL 服务器?甲骨文? ...
  • 附注:即使举个例子,当它不是表的唯一 ID 时,命名列 ID 也是一个坏主意。
  • 嗯,通常人们知道自己正在使用什么数据库系统。 TOAD 听起来像甲骨文。试试select * from v$version。这行得通吗?

标签: sql filter


【解决方案1】:

ID 3 也应包括在内。满足你的条件。

SELECT distinct id
FROM tab1 aa
WHERE aa.order IN (1, 2, 3) AND aa.data IS NULL
      AND NOT exists(SELECT 1
                     FROM tab1 bb
                     WHERE ((bb.order IN (1, 2, 3) AND bb.data IS NOT NULL) 
OR
(bb.order NOT IN (1, 2, 3) AND bb.data IS NULL))
                           AND aa.id = bb.id);

如果你不想要 ID 2 因为它在 ID 4 中有顺序,那么放宽最后一个条件:

bb.order NOT IN (1, 2, 3) 

不检查日期。

如果有 (1,2,3)中的所有“顺序”
你的意思是应该有一个 1 的订单,一个 2 的订单和一个 3 的订单,那么你应该在查询中添加并存在来检查这个,比如

and exists (select 1 form tab1 cc where aa.id = cc.id and cc.order = 1 and cc.data is not null)

等等。

【讨论】:

  • Distinct 不起作用,它是select distinct 的一部分,适用于整个选定的行。删除多余的括号以使代码更清晰,即只需执行 'SELECT DISTINCT id ...`。
  • @jarlh 你为什么说多余的括号?就像:((A和B)OR(C和D))条件,除非更改过滤器的含义,否则我不能删除括号。我更新了不同的,谢谢你的提示。 sqlfiddle.com/#!9/6af0a9/11
  • 对不起,你有SELECT distinct (id) - 括号是多余的。我不是在谈论其他人。
【解决方案2】:

您希望每个 ID 都有一个结果,所以GROUP BY 它。您只对订单 1、2 和 3 感兴趣,因此请使用 WHERE 子句。您只需要包含所有三个订单且未设置日期的 ID。您可以在 HAVING 子句中聚合后检查这一点。

select id
from mytable
where "order" in (1,2,3)
group by id
having count(*) = 3 -- all three IDs
and count("date") = 0; -- no non-null date

Rextester 演示:http://rextester.com/SEE91944

(我推测表的唯一键是id + order。否则你必须COUNT(DISTINCT "order") 并且可能以不同的方式检查空日期。因为orderdate 都是SQL 词,我我在它们上使用引号。你应该避免这样的名字。)

【讨论】:

  • 这是什么意思?什么是“小团体”?对于您的示例数据,它会检索 ID 2,这正是您所要求的。看我的查询。明白它。它和你想要的有什么不同? id + order 在表中是唯一的吗?如果不是,这将如何影响结果?
【解决方案3】:

我不确定您使用的是什么数据库,所以我尝试纠正一个最适用的查询。看看:

select * from
(select 
   id,
   SUM(case
      when [order] = 1 and [date] is  null then 1
      when [order] = 2 and [date] is  null then 1
      when [order] = 3 and [date] is  null then 1
      else 0
   end) score
from test
group by id) scores
where score = 3 

http://sqlfiddle.com/#!18/e4334/9

【讨论】:

    【解决方案4】:

    抱歉,以上都没有解决我的问题。

    我使用“不存在的地方”解决了它(不包括不需要的)

    感谢大家的努力。

    【讨论】:

      【解决方案5】:

      如果我正确地解释了您的问题,下面的 SQL 就可以了。

      它返回记录的id 值,所有订单 具有123 值的所有日期 值都具有null 值> 领域:

      SELECT DISTINCT id
      FROM t
      WHERE
          order IN (1, 2, 3) AND
          date IS NULL AND
          id NOT IN (
              SELECT id
              FROM t
              WHERE
                  order IN (1, 2, 3) AND
                  date IS NOT NULL
          )
      

      【讨论】:

      • Distinct 不起作用,它是select distinct 的一部分,适用于整个选定的行。删除多余的括号以使代码更清晰,即只需执行 'SELECT DISTINCT id ...`。
      • @jarlh:你是对的。我已经更新了答案,感谢您的建议
      • 它不起作用,它还带来了其他空值,我只想要所有1,2,3都为空的那个,而不是一个一个
      • @determinator:我已经更新了答案,请检查它是否有效
      • @determinator:如果我的回答解决了问题,请accept it
      猜你喜欢
      • 1970-01-01
      • 2018-07-31
      • 2021-07-05
      • 2019-12-16
      • 1970-01-01
      • 2019-03-02
      • 1970-01-01
      • 2015-07-14
      • 1970-01-01
      相关资源
      最近更新 更多