[SQL] GROUP BY агрегатные функции и произвольный ряд
за один проход
стало быть, вложенный селект не катит?
Может, СУБД его соптимизирует до одного прохода.
То есть нужно в одном SELECT-е узнать MAX какого-то столбца и значение столбца по определенной строке? Приведи пример на SQL, ну то есть, как бы ты хотел, чтобы это выглядело на SQL.
select max(c1 c2, c3, с6 from t1 group by c2, c4 having avg(c5)=789;
при этом вытащенные значения с2, с3, с6 должны относиться к одному и тому же ряду.
как будет выглядеть — не суть важно, лишь бы оптимизатор не тупил
select max(c1 c2, c3, с6 from t1 group by c2, c4 having avg(c5)=789;какое из c3 должен вывести запрос, если группировка идет по c2 и c4?
при этом вытащенные значения с2, с3, с6 должны относиться к одному и тому же ряду.
То/те, которые находятся в строке(-ах) с максимальным c1?
То/те, которые находятся в строке(-ах) с максимальным c1?а если их несколько?
Вот мне тоже интересно.
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
Мне кажется, если четко сформулировать, что нужно от запроса, то запрос построить нет проблем. SQL не вчера изобретен. Если возникают траблы, они чаще всего от неверно сформулированной претензии к запросу.
Реальная задача: у строк есть рейтинг, кроме того есть отношение эквивалентности. Хочется выбрать любую строку максимального рейтинга, имеющую максимальное количество эквивалентных. Стандартно — только джойнить с собой.
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 обрезает нахрен все после собаки. Как вам такой вариант?
Как вам такой вариант?тут говорили об оптимальности?..
по-моему на большой таблице это оптимальнее, чем джойнить с собой. нет?
как раз на большой таблице у тебя потратится много гигабайт памяти на хранения результата конкатенации...
это без промежуточного результата нельзя сделать, поэтому подзапрос будет как ни крути
да лан? где он будет хранится? из конкатената сразу отрезается одна строчка.
до того как он будет посчитан?
Сумма памяти, отводимая под конкатенаты равна сумме памяти, отведенной под полный ряд строк. Группы-то непересекаются. Поэтому я ВООБЩЕ не понимаю, к чему базар за память?
Сумма памяти, отводимая под конкатенаты равна сумме памяти, отведенной под полный ряд строк.ты прав.
а кто собирается "полный ряд строк" держать в памяти?
Я очень даже могу быть неправ, потому что опыт у меня маловат, но надо же как-то отучать флокал безрезультатного флейма в каждом помогите-посте. (:
АВТОР, ДАМП ТАБЛИЦЫ В АПЛОАД И В СТУДИЮ
если хочешь, прогони тестов, забавно будет, данные заноси рандомные, на пару десятков гигов
у меня нет столько места. Я не хочу рандомные данные. Оптимизация зависит от того, что в таблице. Поэтому я хочу живую таблицу. Оптимизация на рандомной таблице 40-гигабайтного размера - это совсем другая задача. Ты просто свой вариант запроса напиши SQL-ный, я его синтаксис для мускула поправлю. От автора еще требуется отношение эквивалентности.
афаик, оптимизация очень слабо зависит от данных в таблице. на таких простых запросах - никак.
Оставить комментарий
hwh2010
В SQL существует способ (GROUP BY) брать от группы рядов всякие агрегатные функции типа MIN и COUNT.Также имеется возможность брать один произвольный ряд: с помощью LIMIT 1 или с помощью DISTINCT ON (Postgresql).
А есть ли возможность (в чистом SQL или в каком-либо диалекте) за один проход брать и произвольный ряд и агрегатную функцию?