与行号计数相关的子查询
Posted
技术标签:
【中文标题】与行号计数相关的子查询【英文标题】:Correlated subquery with row number count 【发布时间】:2020-08-07 19:25:57 【问题描述】:我有一个如下表,我想要的是使用每个 uid 组的 id 最少的初始行。
表格如下
_id uid type
1 a a
2 b bbb #satisfied
3 b ccc
4 b aaa #satisfied
5 a aaa #satisfied
6 b eee
我已经可以使用以下相关子查询获取初始行
SELECT *
FROM table
WHERE _id IN (
SELECT MIN(_id)
FROM table
WHERE type IN ('aaa','bbb')
GROUP BY uid
);
但是,我希望第 4 列显示满足条件 (type IN ('aaa','bbb')
) 的行数,如下所示 cnt
:
_id uid type cnt
5 a aaa 1
2 b bbb 2
我想我可以计算这个使用几个连接,然后将结果连接到我的代码中......但这很丑......有没有什么优雅的方法来实现这个......
【问题讨论】:
【参考方案1】:你可以试试这个:
SELECT t1.*, t2.cnt
FROM table t1 INNER JOIN (
SELECT MIN(_id) AS id, COUNT(_id) AS cnt
FROM table
WHERE type IN ('aaa','bbb')
GROUP BY uid
) t2 ON t1._id = t2.id
ORDER BY t1.uid
【讨论】:
【参考方案2】:如果您运行的是 mysql 8.0,则可以为此使用窗口函数:
select _id, uid, type, cnt
from (
select
t.*,
count(*) over(partition by uid) cnt,
row_number() over(partition by uid order by _id) rn
from mytable t
where type in ('aaa', 'bbb')
) t
where rn = 1
【讨论】:
【参考方案3】:您可以在没有子查询的情况下执行此操作。在 MySQL 8+ 中,你可以使用这个逻辑:
SELECT DISTINCT MIN(_id) OVER (PARTITION BY uid) as _id,
uid,
FIRST_VALUE(type) OVER (PARTITION BY uid ORDER BY _id) as type,
COUNT(*) OVER (PARTITION BY uid) as cnt
FROM table
WHERE type IN ('aaa', 'bbb');
不幸的是,MySQL 没有“第一”聚合函数,但如果你喜欢的话,有一个技巧:
SELECT MIN(_id) as _id, uid,
SUBSTRING_INDEX(GROUP_CONCAT(type ORDER BY _id), ',', 1) as type,
COUNT(*) as cnt
FROM table
WHERE type IN ('aaa', 'bbb')
GROUP BY uid;
【讨论】:
以上是关于与行号计数相关的子查询的主要内容,如果未能解决你的问题,请参考以下文章
Django:如何从与用户相关的子查询集中获取不同的父列表?