具有行数计数的相关子查询

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;