Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Выборка максимальных записей / 8 сообщений из 8, страница 1 из 1
13.11.2020, 20:34
    #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
13.11.2020, 21:11
    #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
13.11.2020, 23:19
    #40018158
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка максимальных записей
...
...
Рейтинг: 0 / 0
14.11.2020, 01:09
    #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
14.11.2020, 23:29
    #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
15.11.2020, 16:26
    #40018531
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выборка максимальных записей
Dimbuch®,

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

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

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


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