Макс агрегат в группе - PullRequest
       4

Макс агрегат в группе

4 голосов
/ 22 октября 2011

У меня есть следующие данные

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

Я хочу получить поле, содержащее:

  • , если group_id не равен NULL, наименьший индекс в этой группе
  • если group_id IS 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 ]

4 голосов
/ 22 октября 2011

Просто создайте встроенное представление, представляющее 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 голос
/ 23 октября 2011

На всякий случай, если вы хотите найти только минимальные значения INDEX для каждой группы, без необходимости выводить всю таблицу и, таким образом, повторять ненулевые 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

То есть, как я уже сказал, повторение ненулевых GROUP_ID значений подавляется.

0 голосов
/ 23 октября 2011

Объединенный «PreQuery» выполняется для всех групп, включая группы NULL.Таким образом, левое соединение даже не требуется.Однако применение «CASE / WHEN» все равно будет видеть запись «NULL» из исходного источника и использовать ее в качестве основы для получения MinIndex (когда он не равен нулю), или просто использовать свою собственную позицию индекса (когда она была нулевой)

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
0 голосов
/ 23 октября 2011

Еще одна попытка:

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
0 голосов
/ 22 октября 2011

Я думаю, что нашел решение:

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, поэтому я не уверен, что это лучший способ решить эту проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...