Вопрос по SQL - группировка с "множественным аггрегированием"
От: shestero  
Дата: 13.02.14 02:45
Оценка:
Буду признателен, если не только поможете, но и поправите с терминологией.

Задачу надо сделать на MySQL, но интересно и на других СУБД.

Есть очень большая таблица, в ней есть колонка с датой.
Как элегантно сделать из неё выборку с группирой по дням, что бы в каждом дне осталось не более N (скажем, произвольных) записей исходной таблицы?

В общем группировка может быть и по нескольким колонкам (а не только по одной дате). И выбирать может захотется не только произвольные, но скажем, минимальные по величине какого-либо числового критерия.

То есть это похоже на аггригирование, но в результате получается не одно значение, а несколько (не более N) для каждой комбинации значений полей, по которой идёт группировка.
Re: Вопрос по SQL - группировка с "множественным аггрегированием"
От: Softwarer http://softwarer.ru
Дата: 13.02.14 07:30
Оценка: +1
Здравствуйте, shestero, Вы писали:

Ну, сходу возникает мысль атрибутировать эти записи по row_number() over (partition by my_date) и затем отфильтровать по <= N. Но не уверен, что в MySQL работают аналитические функции.
Re: Вопрос по SQL - группировка с "множественным аггрегированием"
От: Olaf Россия  
Дата: 13.02.14 16:41
Оценка:
Здравствуйте, shestero, Вы писали:

S>Буду признателен, если не только поможете, но и поправите с терминологией.


S>Задачу надо сделать на MySQL, но интересно и на других СУБД.

S>...

С использованием MS SQL 2005+ задачу можно решить через аналитические функции...
-- Количество записей в группе
declare @n int = 2

select *
from
(
    select *, (row_number() over(partition by dt order by c) - 1) / @n as n
    from
    (
       select 'A' as c, '2012-01-30' as dt, 5 as m union all
       select 'B' as c, '2012-01-30' as dt, 4 as m union all
       select 'C' as c, '2012-01-30' as dt, 3 as m union all
       select 'F' as c, '2013-06-11' as dt, 1 as m union all
       select 'G' as c, '2013-06-11' as dt, 0 as m union all
       select 'H' as c, '2013-06-11' as dt, 6 as m union all
       select 'I' as c, '2013-06-11' as dt, 7 as m union all
       select 'J' as c, '2013-06-11' as dt, 8 as m
    ) a
) b
where b.n = 0

В каждой из дат dt останется по две записи.
Re: Вопрос по SQL - группировка с "множественным аггрегированием"
От: biochemist СССР https://www.anekdot.ru/i/caricatures/normal/20/7/27/1595846503.jpg
Дата: 13.02.14 18:09
Оценка:
Здравствуйте, shestero, Вы писали:

S>Задачу надо сделать на MySQL, но интересно и на других СУБД.

Oracle — ?

S>Есть очень большая таблица, в ней есть колонка с датой.

S>Как элегантно сделать из неё выборку с группирой по дням, что бы в каждом дне осталось не более N (скажем, произвольных) записей исходной таблицы?
Об элегантности не сужу, но без аналитических функций делают примерно так:
select bt.*
from big_table bt,
    (select a.rowid rid, b.count(*) cnt
    from big_table a, big_table b
    where a.date_column = b.date_column
    and a.rowid >= b.rowid
    group by a.rowid) sq
where bt.rowid = sq.rid
and sq.cnt <= 7


Запрос не проверял (негде).
Вместо оракловского rowid можно использовать первичный ключ.
«Национализм во мне столь естественный, что никогда никаким интернационалистам его из меня не вытравить»
Менделеев Д. И.
Re[2]: Вопрос по SQL - группировка с "множественным аггрегированием"
От: wildwind Россия  
Дата: 14.02.14 06:32
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Ну, сходу возникает мысль атрибутировать эти записи по row_number() over (partition by my_date) и затем отфильтровать по <= N. Но не уверен, что в MySQL работают аналитические функции.


Пока не работают. Но в MySQL в запросе можно использовать (и менять) переменные. Можно реализовать через них.

Думаю, можно и на чистом ANSI SQL, но очень неэффективно выйдет.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.