[SQL] GROUP BY агрегатные функции и произвольный ряд

hwh2010

В SQL существует способ (GROUP BY) брать от группы рядов всякие агрегатные функции типа MIN и COUNT.
Также имеется возможность брать один произвольный ряд: с помощью LIMIT 1 или с помощью DISTINCT ON (Postgresql).
А есть ли возможность (в чистом SQL или в каком-либо диалекте) за один проход брать и произвольный ряд и агрегатную функцию?

Realist

за один проход

стало быть, вложенный селект не катит?
Может, СУБД его соптимизирует до одного прохода.

milanadiana

То есть нужно в одном SELECT-е узнать MAX какого-то столбца и значение столбца по определенной строке? Приведи пример на SQL, ну то есть, как бы ты хотел, чтобы это выглядело на SQL.

ronjke

я бы хотел, чтобы это выглядело например так:
select max(c1 c2, c3, с6 from t1 group by c2, c4 having avg(c5)=789;

при этом вытащенные значения с2, с3, с6 должны относиться к одному и тому же ряду.
как будет выглядеть — не суть важно, лишь бы оптимизатор не тупил

milanadiana

select max(c1 c2, c3, с6 from t1 group by c2, c4 having avg(c5)=789;
при этом вытащенные значения с2, с3, с6 должны относиться к одному и тому же ряду.
какое из c3 должен вывести запрос, если группировка идет по c2 и c4?

Cnac

То/те, которые находятся в строке(-ах) с максимальным c1?

serega1604

То/те, которые находятся в строке(-ах) с максимальным c1?
а если их несколько?

Cnac

Вот мне тоже интересно.

Papazyan

Туманно выражаешься, но ответ в любом случае - есть такие диалекты. Только тебе это не поможет.

q)t:([] a: 1 1 2 2 3 3; b: 1 2 3 4 5 6; c: 1 1 2 2 1 1)
q)select max b,first c by a from t where 1=(avg;c) fby a
a| b c
-| ---
1| 2 1
3| 6 1

milanadiana

Мне кажется, если четко сформулировать, что нужно от запроса, то запрос построить нет проблем. SQL не вчера изобретен. Если возникают траблы, они чаще всего от неверно сформулированной претензии к запросу.

hwh2010

Реальная задача: у строк есть рейтинг, кроме того есть отношение эквивалентности. Хочется выбрать любую строку максимального рейтинга, имеющую максимальное количество эквивалентных. Стандартно — только джойнить с собой.

milanadiana

допустим есть некая функция EQVL, и твое отношение эквивалентности выглядит так
s1 ~ s2 если EQVL(s1) = SQVL(s2)
тогда запрос (пишу от балды, работать не будет) ты хочешь, чтобы выглядел как-то так:
====
SELECT str, MAX(rate COUNT(DISTINCT id)
FROM tbl
ORDER BY rate
GROUP BY EQVL(str)
====
MAX(rate) выбирает максимальный рейтинг из группки эквивалентных строк,
COUNT(id) выбирает количество эквивалентных строк в группке
остается вопрос - как вывести str?
В голову приходит такой вариант:
SELECT OBREZ(GRPOUP_CONCAT(str SEPARATOR '@' MAX(rate COUNT(DISTINCT id)
FROM tbl
ORDER BY rate
GROUP BY EQVL(str)
ну а функция OBREZ обрезает нахрен все после собаки. Как вам такой вариант?

klyv

Как вам такой вариант?
тут говорили об оптимальности?..

milanadiana

по-моему на большой таблице это оптимальнее, чем джойнить с собой. нет?

klyv

как раз на большой таблице у тебя потратится много гигабайт памяти на хранения результата конкатенации...

kindr-16

это без промежуточного результата нельзя сделать, поэтому подзапрос будет как ни крути

milanadiana

да лан? где он будет хранится? из конкатената сразу отрезается одна строчка.

klyv

до того как он будет посчитан? :)

milanadiana

Сумма памяти, отводимая под конкатенаты равна сумме памяти, отведенной под полный ряд строк. Группы-то непересекаются. Поэтому я ВООБЩЕ не понимаю, к чему базар за память?

klyv

Сумма памяти, отводимая под конкатенаты равна сумме памяти, отведенной под полный ряд строк.
ты прав.
а кто собирается "полный ряд строк" держать в памяти?

milanadiana

Давай решим этот вопрос бенчмарком. Попросим у автора дамп таблицы (хочется, чтобы таблица была жирненькая) и напишем запросы. Сравним в миллисекундах и память посмотрим. Ты напиши запрос под мускул и я прогоню на своем компе.
Я очень даже могу быть неправ, потому что опыт у меня маловат, но надо же как-то отучать флокал безрезультатного флейма в каждом помогите-посте. (:
АВТОР, ДАМП ТАБЛИЦЫ В АПЛОАД И В СТУДИЮ

klyv

мускуля у меня нету сходу в доступе и ставить лень, так что с ним помочь не могу.
если хочешь, прогони тестов, забавно будет, данные заноси рандомные, на пару десятков гигов :)

milanadiana

у меня нет столько места. Я не хочу рандомные данные. Оптимизация зависит от того, что в таблице. Поэтому я хочу живую таблицу. Оптимизация на рандомной таблице 40-гигабайтного размера - это совсем другая задача. Ты просто свой вариант запроса напиши SQL-ный, я его синтаксис для мускула поправлю. От автора еще требуется отношение эквивалентности.

klyv

афаик, оптимизация очень слабо зависит от данных в таблице. на таких простых запросах - никак.
Оставить комментарий
Имя или ник:
Комментарий: