【问题标题】: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

我想我可以计算这个使用几个连接,然后将结果连接到我的代码中......但这很丑......有没有什么优雅的方法来实现这个......

【问题讨论】:

    标签: mysql sql select group-by greatest-n-per-group


    【解决方案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;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多