Как выбрать первую строку для каждой группы в MySQL?

В C# это было бы похоже на это:

table
   .GroupBy(row => row.SomeColumn)
   .Select(group => group
       .OrderBy(row => row.AnotherColumn)
       .First()
   )

Linq-To-Sql переводит его в следующий код T-SQL:

SELECT [t3].[AnotherColumn], [t3].[SomeColumn]
FROM (
    SELECT [t0].[SomeColumn]
    FROM [Table] AS [t0]
    GROUP BY [t0].[SomeColumn]
    ) AS [t1]
OUTER APPLY (
    SELECT TOP (1) [t2].[AnotherColumn], [t2].[SomeColumn]
    FROM [Table] AS [t2]
    WHERE (([t1].[SomeColumn] IS NULL) AND ([t2].[SomeColumn] IS NULL))
      OR (([t1].[SomeColumn] IS NOT NULL) AND ([t2].[SomeColumn] IS NOT NULL)
        AND ([t1].[SomeColumn] = [t2].[SomeColumn]))
    ORDER BY [t2].[AnotherColumn]
    ) AS [t3]
ORDER BY [t3].[AnotherColumn]

Но это является несовместимым с MySQL.

57
задан ekad 29 January 2017 в 10:15
поделиться

4 ответа

Когда я пишу

SELECT AnotherColumn
FROM Table
GROUP BY SomeColumn
;

Это работает. IIRC в других СУБД такой оператор невозможен, потому что столбец, который не принадлежит к ключу группировки, упоминается без какой-либо агрегации.

Эта «причуда» очень похожа на то, что я хочу. Поэтому я использовал его, чтобы получить желаемый результат:

SELECT * FROM 
(
 SELECT * FROM `table`
 ORDER BY AnotherColumn
) t1
GROUP BY SomeColumn
;
20
ответ дан 24 November 2019 в 19:30
поделиться

Я основывал свой ответ только на заголовке вашего сообщения, так как я не знаю C # и не понял данный запрос. Но в MySQL я предлагаю вам попробовать подзапросы. Сначала получите набор первичных ключей интересных столбцов, затем выберите данные из этих строк:

SELECT somecolumn, anothercolumn 
  FROM sometable 
 WHERE id IN (
               SELECT min(id) 
                 FROM sometable 
                GROUP BY somecolumn
             );
72
ответ дан 24 November 2019 в 19:30
поделиться

Вот еще один способ, которым не нужно это поле идентификатора.

select some_column, min(another_column)
  from i_have_a_table
 group by some_column

Тем не менее, я согласен с lfagundes, что вам следует добавить некоторый первичный ключ ..

Также помните, что, сделав это, вы не сможете (легко) получить другие значения в той же строке, что и результирующая пара some_colum, another_column! Для этого вам понадобится lfagundes apprach и ПК!

16
ответ дан 24 November 2019 в 19:30
поделиться

Вы должны использовать некоторую агрегатную функцию, чтобы получить желаемое значение AnotherColumn. То есть, если вам нужно наименьшее значение AnotherColumn для каждого значения SomeColumn (численно или лексикографически), вы можете использовать:

SELECT SomeColumn, MIN(AnotherColumn)
FROM YourTable
GROUP BY SomeColumn

Некоторые, надеюсь, полезные ссылки:

http://dev.mysql.com/doc/ refman / 5.1 / en / group-by-functions.html

http://www.oreillynet.com/databases/blog/2007/05/debunking_group_by_myths.html

6
ответ дан 24 November 2019 в 19:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: