具有行数计数的相关子查询
Correlated subquery with row number count
我有一个 table 如下,我想要的是使用获取每个 uid 组的最小 id 的初始行。
table如下
_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
我想我可以计算这个使用几个连接然后将结果连接到我的代码中...但这很难看...有什么优雅的方法可以实现这个...
你可以试试这个:
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
如果你是 运行 MySQL 8.0,你可以只使用 window 功能:
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
您可以在没有子查询的情况下执行此操作。在 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 没有 "first" 聚合函数,但如果您愿意,可以使用一个技巧:
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;
我有一个 table 如下,我想要的是使用获取每个 uid 组的最小 id 的初始行。
table如下
_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
我想我可以计算这个使用几个连接然后将结果连接到我的代码中...但这很难看...有什么优雅的方法可以实现这个...
你可以试试这个:
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
如果你是 运行 MySQL 8.0,你可以只使用 window 功能:
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
您可以在没有子查询的情况下执行此操作。在 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 没有 "first" 聚合函数,但如果您愿意,可以使用一个技巧:
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;