按 id 和某些条件过滤掉数据分组

Posted

技术标签:

【中文标题】按 id 和某些条件过滤掉数据分组【英文标题】:Filtering out the data grouping by id and some condition 【发布时间】:2021-05-09 23:49:45 【问题描述】:

我有一个使用 Sql 获取数据的要求,如下所示

someid  | passengertype  | somename |
--------+----------------+-----------
123     | 3              | abc      |
123     | 6              | zxc      |
111     | 4              | qwe      |
111     | 6              | poi      |
222     | 2              | lkj      |
563     | 1              | uyt      |
563     | 2              | mnb      |
563     | 6              | oiu      |

我只想选择按 someid 分组的记录,其中乘客类型不是 3 和 6。即,对于 someid,如果乘客类型仅包含 3 或 6,则不要选择该 ID,如果 3 或 6 与其他乘客 ID 存在,则选择。所需的输出应该是:

someid  | passengertype  | somename |
--------+----------------+-----------
111     | 4              | qwe      |
111     | 6              | poi      |
222     | 2              | lkj      |
563     | 1              | uyt      |
563     | 2              | mnb      |
563     | 6              | oiu      |

【问题讨论】:

如果您想要原始行,那么group by 似乎不合适。这会减少行数。 【参考方案1】:

您可以使用 not exists 。 . .两次:

select t.*
from t
where not exists (select 1
                  from t t2
                  where t2.someid = t.someid and t2.passengertype = 3
                 ) or
      not exists (select 1
                  from t t2
                  where t2.someid = t.someid and t2.passengertype = 6
                 ) ;

如果您只想要满足此条件的 someid 值,那么聚合将是合适的:

select someid
from t
group by someid
having sum(case when passengertype = 3 then 1 else 0 end) = 0 or
       sum(case when passengertype = 6 then 1 else 0 end) = 0;

【讨论】:

【参考方案2】:

您可以将解析功能用作 dollows:

Select * from
(Select t.*,
       Count(*) over (partition by id) as total_cnt,
       Count(case when passenger_type in (3,6) then 1 end) over(partirion by id) as target_cnt
  From your_table t) t
 Where total_cnt != target_cnt

【讨论】:

以上是关于按 id 和某些条件过滤掉数据分组的主要内容,如果未能解决你的问题,请参考以下文章

r - 按日期过滤,按条件分组

Dexie JS - 结合条件过滤器和文本搜索

LINQ:根据某些条件过滤项目列表,并按条件执行某些操作

Flutter:根据某些条件过滤列表

Python 数据处理(三十九)—— groupby(过滤)

熊猫:按多个条件过滤组?