powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Выборка максимальных записей
8 сообщений из 8, страница 1 из 1
Выборка максимальных записей
    #40018116
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть таблица с полями id, a, b, c, d......

Мне нужно наложить на таблицу некоторые условия фильтрации, а потом вытащить все записи с максимальным значением поля b в рамках группы a, а если таких записей несколько, то взять с максимальным id

Сейчас я родил такого монстра
Код: 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.
28.
SELECT
  t.*
FROM
  mytable.t
  JOIN (
    SELECT
      MAX(t.id) AS id
    FROM
      mytable.t
      JOIN (
        SELECT
          t.a,
          MAX(t.b) AS b
        FROM
          mytable.t
        WHERE
           /* Filter */
        GROUP BY
          t.a
      ) sub ON (
        t.a = sub.a AND
        t.b = sub.b
      )
    GROUP BY
       t.a
  ) sub ON (
    t.id = sub.id
  )

Что-то менее громоздкое можно придумать?

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Выборка максимальных записей
    #40018119
Dimbuch®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
WITH cte_tbl AS (
   -- ваша исходная таблица с условиями
   SELECT 1 AS id, 'group1' AS grp, 1 AS b FROM rdb$database
   UNION ALL SELECT 2 AS id, 'group2' AS grp, 5 AS b  FROM rdb$database
   UNION ALL SELECT 3 AS id, 'group2' AS grp, 5 AS b  FROM rdb$database  -- Из группы group2 выведет эту строку
   UNION ALL SELECT 4 AS id, 'group2' AS grp, 3 AS b  FROM rdb$database
   UNION ALL SELECT 5 AS id, 'group2' AS grp, 2 AS b  FROM rdb$database
   UNION ALL SELECT 6 AS id, 'group3' AS grp, 2 AS b  FROM rdb$database
),
cte_max AS (
  SELECT t.grp, MAX(t.b) AS b_max
  FROM cte_tbl t
  GROUP BY t.grp
),
cte_res AS (
  SELECT t.id, t.grp, t.b, ROW_NUMBER() OVER (PARTITION BY t.grp ORDER BY t.id DESC) AS rn
  FROM cte_tbl t
    INNER JOIN cte_max m
      ON m.grp = t.grp
      AND m.b_max = t.b
)
SELECT *
FROM cte_res
WHERE rn = 1
...
Рейтинг: 0 / 0
Выборка максимальных записей
    #40018158
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
...
Рейтинг: 0 / 0
Выборка максимальных записей
    #40018185
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня, с божьим гуглом, как-то так в итоге получилось (но я не настоящий сварщик):
Код: sql
1.
2.
3.
4.
5.
with cm as
  ( select * from mtbl where /* Filter */ )
select s.* from cm s
  left join cm f on f.a = s.a and (s.b < f.b or (s.b = f.b and s.id < f.id))
  where f.b is null
...
Рейтинг: 0 / 0
Выборка максимальных записей
    #40018393
Dimbuch®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp,

С оконной функцией на реальной таблице быстрее работает, чем с JOIN

Пример на таблице 110 тыс. записей

C JOIN
Код: plaintext
1.
2.
------ Performance info ------
Prepare time = 15ms
Execute time =  4s 875ms 


С оконной функцией на той же таблице
Код: plaintext
1.
2.
------ Performance info ------
Prepare time = 16ms
Execute time =  406ms 
...
Рейтинг: 0 / 0
Выборка максимальных записей
    #40018531
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimbuch®,

В ТЗ было "менее громоздкое", а не "более оптимальное" 😁
...
Рейтинг: 0 / 0
Выборка максимальных записей
    #40018534
Dimbuch®
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp,

Пример с INNER JOIN очень хороший.
Можно на сообразительность кандидатам на собеседовании давать.
...
Рейтинг: 0 / 0
Выборка максимальных записей
    #40018884
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
В ТЗ было "менее громоздкое", а не "более оптимальное" 😁
Да. Но не настолько же :)

На реальной базе, при минимальной фильтрации мой запрос и Dimbuch выполняются примерно одинаково, менее секунды. (У Dimbuch немного меньше чтения). Твой запрос выполняется порядка 5 секунд
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Выборка максимальных записей
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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