2014-10-29 3 views
1

У mytable есть автоинкрементарный id столбец, который является целым числом, и в этом случае можно с уверенностью предположить, что более высокий идентификатор представляет собой последнее значение. mytable также имеет индексный столбец group_id, который является внешним ключом для таблицы groups.Как выполнить динамический запрос UNION в MySQL?

Я хочу быстрый и грязный запрос, чтобы выбрать 5 последних строк для каждого group_id от mytable.

Если бы было только три группы, это было бы легко, как я мог бы сделать это:

SELECT * FROM `mytable` WHERE `group_id` = 1 ORDER BY `id` DESC LIMIT 5 
UNION ALL 
SELECT * FROM `mytable` WHERE `group_id` = 2 ORDER BY `id` DESC LIMIT 5 
UNION ALL 
SELECT * FROM `mytable` WHERE `group_id` = 3 ORDER BY `id` DESC LIMIT 5 

Однако, существует не фиксированное число групп. Группы определяются тем, что находится в таблице groups, поэтому есть неопределенное количество из них.

Мои мысли до сих пор:

  • я мог захватить CURSOR на groups таблицу и построить новую строку SQL запроса, то EXECUTE он. Однако это кажется действительно беспорядочным, и я надеюсь, что есть лучший способ сделать это.
  • Я мог бы захватить CURSOR на столе groups и вставить вещи во временную таблицу, а затем выбрать из этого. Однако это также кажется действительно беспорядочным.
  • Я не знаю, могу ли я просто захватить CURSOR, а затем начать возвращать строки прямо оттуда. Возможно, что-то похожее на переменные типа SQL Server @table?
  • Что я больше всего надеюсь, это то, что я переусердствую это, и есть способ сделать это в инструкции SELECT.

ответ

1

Чтобы получить n самых последних строк на группу, лучше всего обрабатывать функции окна в других СУБД (SQL Server, Postgre Sql, Oracle и т. Д.). Но, к сожалению, у MySql нет никаких оконных функций, поэтому для альтернативы есть решение использовать пользовательские переменные, чтобы присвоить ранг для строк, которые принадлежат к одной группе в данном случае ORDER BY group_id,id desc важно упорядочить результаты должным образом на группу

SELECT c.* 
FROM (
SELECT *, 
@r:= CASE WHEN @g = group_id THEN @r + 1 ELSE 1 END rownum, 
@g:=group_id 
FROM mytable 
CROSS JOIN(SELECT @g:=NULL ,@r:=0) t 
    ORDER BY group_id,id desc 
) c 
WHERE c.rownum <=5 

Выше запроса даст вам 5 последних строк для каждого group_id и если вы хотите получить более 5 строк, просто измените, где фильтр внешнего запроса на нужный номер WHERE c.rownum <= n

+0

Где я могу узнать больше о том, что вы здесь делаете? Я никогда раньше не видел синтаксис '@x: ='. – SoaperGEM

+0

@SoaperGEM здесь является одним из хороших учебников http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/ –

Смежные вопросы