【问题标题】:How to filter values in column by values in other column in sql如何在sql中按其他列中的值过滤列中的值
【发布时间】:2021-11-13 23:22:17
【问题描述】:

我有一个数据框:

id    value
a1      0
a1      1
a1      2
a1      3
a2      0
a2      1
a3      0
a3      1
a3      2
a3      3

我想过滤 id 并只留下值从 0 到 3 (0,1,2,3) 的那些。所以在这个例子中 id a2 必须被删除,因为它只有值 0 和 1。所以想要的结果是:

id    value
a1      0
a1      1
a1      2
a1      3
a3      0
a3      1
a3      2
a3      3

如何做到这一点?

【问题讨论】:

  • 如果你也有一行(a1, 15),是否应该返回? (您可以编辑您的问题并将该行添加到示例数据中,以使事情更清楚。)
  • @jarlh 是的,应该
  • 不要用多个数据库标记您的问题。您使用的是 MySQL 还是 Presto?只标记您真正使用的那个。您还应该清楚在此范围之外是否存在其他值。

标签: mysql sql presto


【解决方案1】:

一个简单的聚合方法是:

SELECT id, value
FROM yourTable
WHERE id IN (
    SELECT id
    FROM yourTable
    WHERE value IN (0, 1, 2, 3)
    GROUP BY id
    HAVING COUNT(DISTINCT value) = 4
);

【讨论】:

  • 谢谢,这部分 WHERE value IN (0, 1, 2, 3) 似乎不可扩展(如果我需要从 0 到 1000,我应该写 1000 个整数)
  • @french_fries 好吧,如果您需要从 0 到 1000 的 all 值,那么您可以使用 WHERE value BETWEEN 0 AND 1000。如果您只需要 0 到 1000 范围内的 某些 值,那就另当别论了,您要么必须列出所有值,要么指定一系列范围。
【解决方案2】:

我建议使用窗口函数,尤其是在您使用 Presto 时。假设行只有这四个值并且行是唯一的:

select t.*
from (select t.*, count(*) over (partition by id) as cnt
      from t
     ) t
where cnt = 4;

如果值可以超出此范围,则可以使用条件聚合:

select t.*
from (select t.*,
             count(case when value in (0, 1, 2, 3) then 1 else 0 end) over (partition by id) as cnt
      from t
     ) t
where cnt = 4;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 2017-10-11
    • 2022-12-21
    • 2020-12-25
    • 1970-01-01
    • 2016-02-08
    相关资源
    最近更新 更多