Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Выбор максимальных значений / 20 сообщений из 20, страница 1 из 1
09.11.2018, 10:35
    #39730339
vdpmr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
Здравствуйте.
Подскажите пожалуйста, как правильно написать запрос.
Допустим, есть таблица:

ID, FIELD, POINT
1, 8, 23
1, 3, 17
1, 4, 12
2, 9, 10
2, 3, 26
2, 6, 7

Нужно для каждого ID вывести строку с максимальным значением POINT.
Что-то типа:

select ID, max(POINT)
from TABLE
group by 1

Но нужно вывести все поля таблицы.
Результат запроса должен быть такой:

1, 8, 23
2, 3, 26
...
Рейтинг: 0 / 0
09.11.2018, 11:20
    #39730394
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
vdpmr,

Версия FB? Поле "Point" уникальное?
...
Рейтинг: 0 / 0
09.11.2018, 11:26
    #39730407
rstrelba
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
vdpmr,

Код: sql
1.
2.
3.
4.
5.
6.
7.
select 
z.ID,
(select first 1 x0.FIELD from TABLE x0 where x0.ID=z.ID and x0.POINT=(select max(z0.POINT) from TABLE z0 where z0.ID=z.ID)) as FIELD,
(select max(z0.POINT) from TABLE z0 where z0.ID=z.ID) as POINT

from TABLE z
group by z.ID
...
Рейтинг: 0 / 0
09.11.2018, 11:48
    #39730425
vdpmr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
KreatorXXIvdpmr,

Версия FB? Поле "Point" уникальное?

KreatorXXI, кстати, я упустил этот момент...
POINT не уникальное поле. Если несколько совпадающих максимальных значений, нужно их все вывести.
Например, из таблицы:

ID, FIELD, POINT
2, 5, 26
1, 8, 23
1, 3, 17
1, 4, 12
2, 9, 10
2, 3, 26
2, 6, 7

Должно получиться:

2, 5, 26
1, 8, 23
2, 3, 26

PS: Firebird 2.5 у меня
...
Рейтинг: 0 / 0
09.11.2018, 12:28
    #39730476
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
vdpmr,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
with q (id, m) as
( select a.id id, max(a.point) m
  from table a
  group by 1
)
select b.*
from table b,
     q
where b.id=q.id and b.point=q.m


Как-то так.
...
Рейтинг: 0 / 0
09.11.2018, 12:33
    #39730485
vdpmr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
KreatorXXI, rstrelba, спасибо за ответы.
...
Рейтинг: 0 / 0
09.11.2018, 13:43
    #39730545
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
vdpmr,

Проверь оба. Подозреваю, запрос от коллеги выдаст только одну запись для каждого id. Что противоречит условиям задачи.
...
Рейтинг: 0 / 0
09.11.2018, 14:56
    #39730623
o_v_a
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
От Креатора красивее
...
Рейтинг: 0 / 0
09.11.2018, 16:08
    #39730731
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
o_v_a,

"from b, q" не может быть красиво по определению.
...
Рейтинг: 0 / 0
12.11.2018, 11:39
    #39731615
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
WildSery,

надо было джойнить? ИМХО, ещё хуже.
...
Рейтинг: 0 / 0
12.11.2018, 11:44
    #39731617
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
KreatorXXI,

а чем явный JOIN хуже неявного? По моему от неявных джойнов одни беды, особенно если вдруг потом этот запрос надо будет модифицировать и добавить ещё один JOIN причём OUTER. Уж лучше сразу написать явный JOIN, чтобы потом переделывать не пришлось
...
Рейтинг: 0 / 0
12.11.2018, 12:01
    #39731630
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
Симонов Денис,

согласен. Джойн по двум полям. Мне, правда, непривычно. Где-то здесь проскакивало, что нехорошо конструкцию "join...on" нагружать дополнительными условиями.
...
Рейтинг: 0 / 0
12.11.2018, 12:34
    #39731658
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
KreatorXXI,

ну я туда часто засовываю более одного условия, особенно для LEFT JOIN.
Обычно в on пишут только условие связи, а where условие фильтрации, но для LEFT JOIN можно и дополнительные условия писать при понимании на что они влияют. Например

Код: sql
1.
2.
3.
SELECT ...
FROM t1 
LEFT JOIN t2 ON t2.id = t1.t2_id AND t1.t2_id > 0



это бывает полезно если в t2 есть спец значение с кодом -1
...
Рейтинг: 0 / 0
12.11.2018, 13:16
    #39731694
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
KreatorXXIГде-то здесь проскакивало, что нехорошо конструкцию "join...on" нагружать дополнительными условиями.Я не видел, и впервые слышу, что это влияет.
Что-то пропустил?

Наоборот, стараюсь все условия по конкретной таблице собрать в условие соединения, поскольку в сложном запросе читать многострочное WHERE глаза сломаешь, даже если по группам всё разделил.
...
Рейтинг: 0 / 0
16.12.2018, 14:34
    #39748597
_shrk_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
Здравствуйте!
У меня похожая задача, но несколько отличающаяся

Дана таблица
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Id,    Date,        Param1,   Param2,   Norma
1,  "01.01.2010",   15,       100,       0.95
2,  "02.01.2010",   18,       200,       0.97
3,  "02.01.2010",   22,       150,       0.94
4,  "03.01.2010",   19,       200,       1.01
5,  "03.01.2010",   14,       220,       0.95
6,  "05.01.2010",   18,       160,       1.05
7,  "05.01.2010",   24,       400,       1.01
8,  "05.01.2010",   20,       220,       0.98

Id - уникален, остальные столбцы могут повторяться.

Нужно для каждой даты вывести строку с параметром Norma наиболее близким к 1.00. Если таких строк несколько, то выдавать любую (или с мин. Id).
Например, для данной таблицы должно получиться:
Код: plaintext
1.
2.
3.
4.
5.
Id,    Date,        Param1,     Param2, Norma
1,  "01.01.2010",    15,        100,      0.95
2,  "02.01.2010",    18,        200,      0.97
4,  "03.01.2010",    19,        200,      1.01
7,  "05.01.2010",    24,        400,      1.01
Запросы, аналогичные приведенным выше, работают, но записей в таблице может быть порядка 100000 (в итоговом результате порядка 10000) и поэтому писать конструкции в стиле select x, (select y ...) from select не очень хочется.
...
Рейтинг: 0 / 0
16.12.2018, 14:49
    #39748600
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
_shrk_,

оконные функции тебе в помощь
...
Рейтинг: 0 / 0
17.12.2018, 11:53
    #39748848
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
_shrk_,

версия FB? Оконные работают начиная только с третьей версии.
...
Рейтинг: 0 / 0
19.12.2018, 20:27
    #39750461
_shrk_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
Версия 2.5 embedded )
В принципе переход на 3.0 возможен, если будет положительный результат
...
Рейтинг: 0 / 0
19.12.2018, 20:43
    #39750468
Vlad F
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
_shrk_,

А что считать положительным результатом?
Твоя задача упомянутым институтом решается на-ура.
Если сумеешь в нем разобраться.))
...
Рейтинг: 0 / 0
22.12.2018, 01:10
    #39751578
_shrk_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбор максимальных значений
В общем разобрался....))
Нарисовал я запрос:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select q.id, q.dta, q.tme, q.param1, q.param2, q.norma from
(
  select t.id as id, cast(t.tme as date) as dta, cast(t.tme as time) as tme, t.param1 as param1, t.param2 as param2, t.norma as norma,
  row_number() over (partition by cast(t.tme as date) order by abs(t.norma-1.000)) as r_n
  from tst t
  where t.a_id = 1
) q
where q.r_n = 1


(a_id - внешний ключ)
Делает то, что надо, на тестовом наборе из 200000 записей отбирает 10000 из них за 2 секунды, делая 200000 чтений из базы.

Но запрос
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select t1.id as id,  cast(t1.tme as date) as dta, cast(t1.tme as time) as tme, t1.param1 as param1, t1.param2 as param2, t1.norma
from tst t1
join
(
  select cast(t2.tme as date) as dta, min(abs(t2.norma-1.000)) as delta
  from tst t2 where t2.a_id = 1
  group by 1
) j
on cast(t1.tme as date) = j.dta and abs(t1.norma-1.000)=j.delta
where t1.a_id = 1
order by 1


выполняется на том-же наборе данных выполняется за 1 секунду, делая 400000 чтений из базы. Правда выдает он не одну строку, соответствующую критерию min(abs(Norma-1.000)), а несколько и в результате получаем 10008 записей))
Вот если бы губы Никанора Ивановича да приставить к носу убрать "лишние" данные из результатов второго запроса...)))
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Выбор максимальных значений / 20 сообщений из 20, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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