【问题标题】:Selecting 2 distinct rows MySQL选择 2 个不同的行 MySQL
【发布时间】:2010-09-27 11:00:05
【问题描述】:

我有一个名为 categories 的表,它有 3 列:id, name, parent_id

ID         name         group_id
==         ==           ==
1          haim         1
2          gil          2
3          alon         1
4          idan         1
5          shai         3
6          adi          2
7          itay         3
8          aviram       1
9          lioz         3
10         amit         2
11         ben          2
12         eran         1

我需要在一个查询中选择每个 group_id 的 2 行,所以结果是:

ID         name         group_id
==         ==           ==
1          haim         1
3          alon         1
2          gil          2
6          adi          2
5          shai         3
7          itay         3

它也将按group_id 排序,这一点非常重要。

谢谢!

【问题讨论】:

  • (1) 为什么要标记 sql-server? (2)每组选择2行返回的标准是什么?

标签: sql mysql group-by distinct


【解决方案1】:
SELECT   id  ,
         name,
         parent_id
FROM     ( SELECT  id      ,
                  name     ,
                  parent_id,
                  CASE
                           WHEN @parent_id = parent_id
                           THEN @rownum   := @rownum + 1
                           ELSE @rownum   := 1
                  END           AS rn,
                  @parent_id :=    parent_id
         FROM     (SELECT 1 as ID, 'haim' as NAME, 1 as parent_id
                   UNION ALL SELECT 2, 'gil', 2      
                   UNION ALL SELECT 3, 'alon', 1
                   UNION ALL SELECT 4, 'idan', 1
                   UNION ALL SELECT 5, 'shai', 3
                   UNION ALL SELECT 6, 'adi', 2
                   UNION ALL SELECT 7, 'itay', 3
                   UNION ALL SELECT 8, 'aviram', 1
                   UNION ALL SELECT 9, 'lioz', 3
                   UNION ALL SELECT 10, 'amit', 2
                   UNION ALL SELECT 11,  'ben', 2
                   UNION ALL SELECT 12, 'eran', 1
                  )
                  YourTable
                  JOIN
                           (SELECT @rownum    := 0,
                                   @parent_id := NULL) r
         ORDER BY parent_id
         )
         x
WHERE    rn<=2

【讨论】:

    【解决方案2】:

    最适应的方法是考虑变量:

    set @rank:=0;
    set @prev:=0;
    select ID,name,group_id from
      ( select ID,name,group_id,@rank:=if(group_id=@prev,@rank+1,1) as rank,@prev:=group_id as dump from 
        ( select ID,name,group_id from categories order by group_id asc) A
      ) A where rank<=2;
    

    这样,您不再依赖于每个 group_id 需要显示的行数。

    方法是:

    • 在第一个子查询中,您按数据分组的字段对行进行排序
    • 第二步,计算组中每一行的排名
    • 在最后一个中,您选择排名低于您需要的行。

    干杯

    纪尧姆

    【讨论】:

      【解决方案3】:

      我考虑了每个 group_id 在表中找到的第一个和第二个 ID。

      SELECT ID, NAME, GROUP_ID
      FROM MYTABLE WHERE ID IN (
          SELECT MIN(ID)
          FROM MYTABLE
          GROUP BY GROUP_ID)
      
      UNION ALL
      
      SELECT ID, NAME, GROUP_ID
      FROM MYTABLE WHERE ID IN (
          SELECT MIN(ID)
          FROM MYTABLE
          WHERE ID NOT IN (
            SELECT MIN(ID)
            FROM MYTABLE
            GROUP BY GROUP_ID
            )
          GROUP BY GROUP_ID)
      ORDER BY GROUP_ID
      

      【讨论】:

        【解决方案4】:

        可能有几种方法可以实现这一点,但我会做两个查询,然后使用 UNION 将它们合并在一起。

        类似这样的:

        (SELECT .... WHERE ID=GROUP_ID)
        UNION
        (SELECT .... GROUP BY GROUP_ID)
        ORDER BY ID;
        

        这是relevant MySQL Manual page

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-10
          • 1970-01-01
          • 2018-05-21
          • 1970-01-01
          • 1970-01-01
          • 2017-07-05
          相关资源
          最近更新 更多