MAX聚合在一个组内

时间:2011-10-22 16:26:34

标签: mysql sql

我有以下数据

 GROUP_ID   INDEX
   NULL       1
     1        2
   NULL       3
     1        4
   NULL       5
     2        6
     2        7

我想要的是获得一个包含以下内容的字段:

  • 如果group_id IS NOT NULL,则为该组中的最小索引
  • 如果group_id为NULL,则从该行开始索引

上述示例的结果数据集将是:

 GROUP_ID   INDEX  GROUP_INDEX_MIN
   NULL       1          1
     1        2          2
   NULL       3          3
     1        4          2
   NULL       5          5
     2        6          6
     2        7          6

在Oracle中我会通过使用(CASE WHEN group_id IS NOT NULL THEN MIN(index) OVER (PARTITION BY group_id) ELSE group_id END)解决这个问题,但由于MySQL不支持,我真的不知道如何继续:)我可以通过使用一个子查询来解决这个问题,该子查询为每个子句检索最小值小组,然后离开加入它,但我认为必须有一个更优雅的解决方案。

如果您需要更多信息,请询问。 感谢。

5 个答案:

答案 0 :(得分:4)

只需创建一个代表min Group_index_min(minT)的内联视图,然后加入它并在group_ID和min之间进行合并

SELECT t.group_id, 
       t.index, 
       Coalesce(t.group_id, minTgroup_index_min) group_index_min 
FROM   yourtable t 
       LEFT JOIN (SELECT group_id, 
                         MIN(index) group_index_min 
                  FROM   yourtable
                  GROUP BY 
                         group_id) minT 
         ON t.group_id = minT.group_id 

答案 1 :(得分:1)

如果您只想为每个组找到最小INDEX值,而不必输出整个表,从而重复非NULL GROUP_ID,您可以尝试以下查询:

SELECT
  GROUP_ID,
  MIN(`INDEX`) AS GROUP_INDEX_MIN
FROM atable
GROUP BY
  GROUP_ID,
  CASE WHEN GROUP_ID IS NULL THEN `INDEX` ELSE GROUP_ID END

应该返回这样的内容:

GROUP_ID  GROUP_INDEX_MIN
--------  ---------------
NULL      1
NULL      3
NULL      5
1         2
2         6

也就是说,正如我所说,非NULL GROUP_ID值的重复被抑制。

答案 2 :(得分:0)

我想我找到了一个解决方案:

SELECT a.group_id, a.index, (CASE WHEN a.group_id IS NOT NULL THEN a.group_index_min ELSE a.index END) group_index_min 
FROM (
SELECT 
    p.group_id, p.index,
    (CASE WHEN @group <> IFNULL(p.group_id, 0) THEN @n := p.index ELSE @n := @n END) group_index_min, 
    @group := IFNULL(p.group_id, 0) 
FROM
    temp p
ORDER BY p.group_id, p.index
) A
ORDER BY
  (CASE WHEN a.group_id IS NOT NULL THEN a.group_index_min ELSE a.index END)

这适用于我的示例,按索引(如果它们不属于某个组)或按组索引(如果它们属于组)对值进行排序。现在尝试申请我的真实表格/数据:)

如果有人愿意查看并说它是否包含一些MySQL DONT,我会非常感激。正如我所说,我不是MySQL专家,所以我不确定这是否是解决这个问题的最佳方法。

答案 3 :(得分:0)

再试一次:

SELECT
    GROUP_ID
  , `INDEX` 
  , COALESCE( ( SELECT MIN(ti.GROUP_INDEX_MIN)
                FROM TableX AS ti
                WHERE ti.GROUP_ID = t.GROUP_ID
              )
            , t.GROUP_INDEX_MIN 
            ) AS GROUP_INDEX_MIN 
FROM
    TableX AS t
ORDER BY
    GROUP_INDEX_MIN

答案 4 :(得分:0)

已为所有组(包括NULL条目的组)完成联接的“PreQuery”。因此,甚至不需要左连接。但是,应用“CASE / WHEN”仍将看到原始源中的“NULL”条目,并将其用作获取MinIndex(非null时)的基础,或者仅使用其自己的索引位置(当它为null时)< / p>

select 
      YT.Group_ID,
      YT.`Index`,
      CASE WHEN YT.GROUP_ID IS NULL 
         THEN YT.`Index` 
         ELSE YT2.MinIndex END as Group_Index_Min
   from
      YourTable YT
         JOIN ( select YT2.Group_ID,
                       MIN( YT2.`Index` ) MinIndex
                    from YourTable YT2
                    group by YT2.Group_ID ) YTMin
            on YT.Group_ID = YTMin.Group_ID