powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
29 сообщений из 29, показаны все 2 страниц
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689012
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FB3. Условный запрос:
Код: sql
1.
2.
3.
select t.value, t.edate
from t
order by 1, 2 desc


Для каждой value есть десятки/сотни edate. Нужно для каждой value ограничить количество выдаваемых edate, например, десятью. Если записей для конкретного value меньше десяти, то выдать сколько есть. Возможно? Посмотрел оконные функции, first, fetch, ничего подходящего не нахожу. Хранимку не хотелось бы. Execute block, for select...do устроили бы.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689014
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то так: select from select group by having
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689016
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
windows functions -> row number partition by t.value

KreatorXXIдля каждой value ограничить количество выдаваемых edate, например, десятью

количество чего конкретно - строк в группе value вообще, или же уникальных значений edate (может быть у тебя будет всего лишь родно edate, но сто строк с ним) ?
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689019
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
за основу посмотри тут: http://www.sql.ru/forum/1283351/zapros-s-gruppirovkoy

но там я брал не десять строк, а только одну
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689045
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

спасибо за наводку. Типа того:
Код: sql
1.
2.
3.
4.
select t.value, t.edate,
         row_number() over (partition by t.value order by t.edate desc)
from t
order by 1, 2 desc


Потом select from select или CTE.
Кстати, в руководстве по языку по оконным функциям похоже нет ни одного примера с одновременным использованием partition by и order by. Что меня и выбило из колеи. Чувствую, что решение где-то здесь...
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689050
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXIКстати, в руководстве по языку по оконным функциям похоже нет ни одного примера с одновременным использованием partition by и order by.

Упс... Добавлю. Оно есть но только в доке по 4.0, и не в явном виде, когда рассказывается уже про именованные окна
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689054
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXIПосмотрел оконные функции, first, fetch, ничего подходящего не нахожу.Значит, плохо смотрел. Строки нумеровать в группе плёвое дело.
KreatorXXIExecute block, for select...do устроили бы.Тоже элементарно. Вложенный for select, пожалуй, будет оптимально, поскольку его легче прервать, когда "хватит".
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689055
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

кстати для понимания как работают оконные функции лучше читать доку по 4.0. В ней рассказывается об одной очень важной части оконных функций (рамки окна), явное задание которой не реализована в 3.0.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689082
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochза основу посмотри тут: http://www.sql.ru/forum/1283351/zapros-s-gruppirovkoy

этот топик бы вообще "приклеить" в начале форума, именно потому что там обсуждались оконные функции в деталях и на полезном для жизни примере
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689287
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
За ночь всё же пришло понимание, что не совсем хорошо. Результат правильный, но записи-то все просматриваются. Не есть хорошо. В текущей базе по времени всё классно. Но в будущем надо будет пересмотреть. Кроме как использовать lateral join на ум ничего не приходит. Нет, ещё можно попробовать циклы for select с явным выходом из них. Ни сердце ни душа к этому не лежит.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689356
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

ну так. Понимать надо что для работы оконных функций требуется буферизация, причём всей выборки целиком, предикаты на CTE не будут прокинуты в окно.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689368
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSeryВложенный for select, пожалуй, будет оптимально, поскольку его легче прервать, когда "хватит".

а вот это не факт. Это сильно зависит от индексов и распределения значений. Иногда full scan сделать дешевле, чем сначала группировку по полю (индекса может и не быть), потом снова выборку по сгруппированному полю + к ещё и сортировку по другому полю.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689369
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

фильтр по row_number в принципе можно бы было и прокидывать сверху вниз, внутрь окна
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689381
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

да, я всё понимаю, к оконным функциям претензий нет. Просто хотелось ещё плюсом поиметь сокращение "фетчей". Идея такая. Отказаться от оконных функций, а сделать типа такого:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select t1.value, t3.edate
from t1
     lateral join (
                    select first 10 t2.edate
                    from t2
                    where t2.t1_id = t1.t1_id
                    order by t2.edate desc
                  ) t3 on true
where t1....


Или нереально придумал?
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689390
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

там много специфики, которая оптимизатором не учтена.

row_number требует сортировки результата, по уму работает только с предложением ORDER BY внутри окна. Сортировка там доступна только планом SORT, т.е. без использования навигации по индексу (ORDER INDEX), потому что могут быть секции заданные PARTITION BY, а может и не быть. Как известно сортировка SORT требует полный фетч. Сам по себе PARTITION BY то же требует сортировки, причём опять же поддерживается только SORT. Не уверен что это можно легко разрулить.

Прокидывание предикатов по полям в PARTITION BY может быть сделана безболезненно, но это только если у нас ровно одно окно или несколько, но с одинаковыми PARTITION BY.

Надо понимать что оконные функции не панацея. В некоторых случаях они значительно могут облегчить жизнь, но не следует их пихать во все щели. По большому счёту они полезны в различных отчётах, но делать с ними живые выборки быстро возвращающие результат не следует.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689399
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

если разработчики будут успевать по срокам lateral join будет в 4.0. Но опять же не факт что в данном случае это будет быстрее. Группировка один фиг требует полного сканирования будь оно сделано NATURAL с сортировкой, или с помощью ORDER INDEX. В первом случае и так будет буферизация, о втором может работать поточно, но полная выборка может потребовать больше чтений с диска (если выборка реально большая). А потом всему этому будет выполняться второй запрос со своим оверхедом. В общем мерить надо. Может получиться дешевле, а может и дороже. Однозначно утверждать что лучше я бы не стал.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689561
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

подождём, посмотрим. Сейчас конструкция first вроде не сканирует всё. Естественно, при наличии правильного индекса. Поэтому можно ожидать хорошего быстродействия приведённого мной запроса.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39689568
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXIСейчас конструкция first вроде не сканирует всё. Естественно, при наличии правильного индекса.

это да, но ты не учитываешь затраты на запрос верхнего уровня в котором есть группировка, и потом дополнительный оверхэд на выборку 10 значений edate для каждого value

Проведи уже эксперимент что быстрее.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39690302
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

Не понял какой эксперимент нужен. Если говорить о том, что сейчас есть (select ... from select ...), то время тратится только на "внутренний" select. Внешний фактически не даёт никакого вклада. А вот с lateral join посмотрим потом. Или в снапшот-сборке четвёрки уже есть lateral join?
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39690305
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

Денис не верит, что верхний запрос, получающий группировки, дешёвый.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39690328
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery,

А как доказать? Собственно, в верхнем нет группировки, там только фильтр по значению row_number. Какое-то недопонимание.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39690343
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

Я уже потерял нить ваших рассуждений. Но вроде так:
Для select from select "верхним" называют "внешний", который будет группировать по value и edate, а "внутренний" уже будет для этих
значений отбирать требуемые максимум 10 записей в каждой группировке.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39690445
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

нет lateral join ещё не делали. Если без него то запрос переписывается примерно так

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
execute block 
rerurns (
  value type of column t.value,
  edate type of column t.edate
)
as
begin
  for select value
       from t
       group by value
       order by value desc
       into :value
  do 
  begin
    for select edate
         from t
         where value = :value
         order by edate desc
         fetch first 10 rows only
         into :edate
    do suspend;
  end
end



так вот. Запрос

Код: sql
1.
2.
3.
4.
select value
from t
group by value
order by value desc



может быть совсем не дешёвым и всё равно делать полный скан таблицы, если так, то разницы с оконными функциями не будет, скорее наоборот блок будет проигрывать. Плюс надо смотреть какой там план у внутреннего запроса, он тоже может быть не очень хорошим
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39690452
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery,

Вот так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select v, e 
from (
select t1.value v, t2.edate e,
         row_number() over (partition by t1.value order by t2.edate desc) r
from t1
       inner join t2 on t2.t1_id = t1.t1_id  
order by 1, 2 desc
)
where r<=10



Я так понимаю, внутренний и отбирает и группирует и сортирует. А во внешнем только фильтр.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39690463
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

а вот быстрый вариант, но при определённых условиях будет примерно тоже самое что с оконными функциями

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
execute block 
rerurns (
  value type of column t.value,
  edate type of column t.edate
)
as
declare old_value type of column t.value;
declare n integer;
begin
  n = 0;
  old_value = null;
  for select value, edate
       from t
       order by value desc, edate desc
       into :value, edate
  do 
  begin
    if (value distinct from old_value) then
    begin
      old_value = value;
      n = 0;
    end  
    n = n + 1;
    if (n <= 10) then
      suspend;
  end
end



заметь full scan всё равно будет, но возможно немного можно выиграть на сортировке
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39690467
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

21648249 это практически не имеет смысла, зачем дважды соединять таблицу сама с собой
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39690480
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXIВот так:Так у тебя value и edate ещё и в таблицах разных?
Понятно тогда, что если в первой таблице value уникальны, то вложенный for select может быть оптимален по производительности.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39690482
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисKreatorXXI,

21648249 это практически не имеет смысла, зачем дважды соединять таблицу сама с собойА я это понял, что две разные таблицы.
...
Рейтинг: 0 / 0
Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
    #39690516
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо за варианты. Запросы тестовые. Реальный начинается с двух блоков CTE. Ими я могу манипулировать, что получить на третьем запросе. А в третьем, посчитал, удобнее через две таблицы (одна из второго блока СТЕ). Получилось более-менее компактно. Ну и результат по скорости очень даже приемлемый. Запущу отчёт в работу. Будет lateral, вернусь. Ещё раз всем спасибо.
...
Рейтинг: 0 / 0
29 сообщений из 29, показаны все 2 страниц
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как в запросе ограничить количество выдаваемых строк в зависимости от значения столбца?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]