Имеется таблица с полями:
— groupid
— time
— cond
— value
Нужно:
— сгруппировать таблицу по groupid
— в каждой группе отсортировать по time
— в отсортированных записях найти первую запись, удовлетворяющую условию (cond=1)
— получить из этой записи значение value
Повторить для каждой groupid. В итоге хочется получить таблицу с полями
— groupid
— value (для данного groupid, алгоритм извлечения — выше)
P.S. Не смог придумать нормальное название для топика
UPD: СУБД mysql
UPD: Сразу и индексы посоветуйте для быстрого выполнения запроса
Здравствуйте, Буравчик, Вы писали:
Б>Помогите составить SQL запрос
Б>Имеется таблица с полями: Б>- groupid Б>- time Б>- cond Б>- value
Б>Нужно: Б>- сгруппировать таблицу по groupid Б>- в каждой группе отсортировать по time Б>- в отсортированных записях найти первую запись, удовлетворяющую условию (cond=1) Б>- получить из этой записи значение value
SELECT groupid, value
FROM TABLE_NAME
WHERE cond=1
GROUP BY groupid
HAVING time= min(time);
Если есть записи с одинаковыми groupid, time, cond — то будут выводиться по несколько записей. Отфильтровать это без чисто Оракловских прибабахов не могу. Вот если бы таблица имела PK...
«Национализм во мне столь естественный, что никогда никаким интернационалистам его из меня не вытравить»
Менделеев Д. И.
Здравствуйте, biochemist, Вы писали:
B>SELECT groupid, value B>FROM TABLE_NAME B>WHERE cond=1 B>GROUP BY groupid B>HAVING time= min(time);
Не, не работает
Такая таблица:
CREATE TABLE mytable (
groupid VARCHAR(5) NOT NULL,
time VARCHAR(5) NOT NULL,
cond VARCHAR(5) NOT NULL,
value VARCHAR(5) NOT NULL
);
INSERT INTO mytable
(groupid, time, cond, value)
VALUES
("g1", "t1", "0", "v1"),
("g1", "t2", "1", "v2"),
("g1", "t3", "0", "v3"),
("g2", "t1", "1", "v4"),
("g2", "t2", "0", "v5"),
("g3", "t4", "1", "v6"),
("g3", "t3", "1", "v7"),
("g3", "t2", "1", "v8"),
("g3", "t1", "0", "v9");
/*
Ожидаемый результат:
g1-v2
g2-v4
g3-v8
*/
На запрос
SELECT groupid, value, time
FROM mytable
WHERE cond=1
GROUP BY groupid
HAVING time=min(time);
Ругается:
[42000][1055] Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'mytable.value' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
Для выполнения запроса пришлось отключить sql_mode=only_full_group_by.
Что это за зверь и какие последствия его отключения?
Ну и самое главное, в результате запрос вывел:
g1 v2
g2 v4
Про группу g3 забыл...
B>Если есть записи с одинаковыми groupid, time, cond — то будут выводиться по несколько записей. Отфильтровать это без чисто Оракловских прибабахов не могу. Вот если бы таблица имела PK...
Здравствуйте, Буравчик, Вы писали:
Б>Такая таблица: Б>[sql]
Б>CREATE TABLE mytable ( Б> groupid VARCHAR(5) NOT NULL, Б> time VARCHAR(5) NOT NULL, Б> cond VARCHAR(5) NOT NULL, Б> value VARCHAR(5) NOT NULL Б>);
Б>INSERT INTO mytable Б> (groupid, time, cond, value) Б>VALUES Б> ("g1", "t1", "0", "v1"), Б> ("g1", "t2", "1", "v2"), Б> ("g1", "t3", "0", "v3"), Б> ("g2", "t1", "1", "v4"), Б> ("g2", "t2", "0", "v5"), Б> ("g3", "t4", "1", "v6"), Б> ("g3", "t3", "1", "v7"), Б> ("g3", "t2", "1", "v8"), Б> ("g3", "t1", "0", "v9");
Б>PK может быть, если нужно, пусть будет id.
SELECT Groupid, values
FROM mytable a WHERE a.cond='1'
AND NOT EXISTS (SELECT 'X'
FROM mytable b
WHERE b.groupid=a.groupid
AND b.cond='1'
AND b.time < a.time -- min время
AND b.id < a.id); -- Если есть уникальный индекс (groupid, time, cond) — то не надо.
Time Varchar(5) — не лучший вариант.
«Национализм во мне столь естественный, что никогда никаким интернационалистам его из меня не вытравить»
Менделеев Д. И.
Здравствуйте, Буравчик, Вы писали:
Б>Нужно: Б>- сгруппировать таблицу по groupid Б>- в каждой группе отсортировать по time Б>- в отсортированных записях найти первую запись, удовлетворяющую условию (cond=1) Б>- получить из этой записи значение value
Б>Повторить для каждой groupid. В итоге хочется получить таблицу с полями Б>- groupid Б>- value (для данного groupid, алгоритм извлечения — выше)
select groupid, (select value from mytable where cond = "1" and groupid = t.groupid order by time limit 1) as value
from mytable t
group by groupid
Б>UPD: СУБД mysql Б>UPD: Сразу и индексы посоветуйте для быстрого выполнения запроса
Здравствуйте, biochemist, Вы писали:
Б>>PK может быть, если нужно, пусть будет id. B>SELECT Groupid, values B>FROM mytable a WHERE a.cond='1' B>AND NOT EXISTS (SELECT 'X' B> FROM mytable b B> WHERE b.groupid=a.groupid B> AND b.cond='1' B> AND b.time < a.time -- min время B> AND b.id < a.id); -- Если есть уникальный индекс (groupid, time, cond) — то не надо.
Да, так работает, спасибо!
B>Time Varchar(5) — не лучший вариант.
Это просто для примера, для составления запроса.
Таблица сложнее — groupid на самом деле составной, value — тоже куча полей и т.п.
NB>select groupid, (select value from mytable where cond = "1" and groupid = t.groupid order by time limit 1) as value
NB>from mytable t
NB>group by groupid
NB>
Работает. Не знал, что так можно: SELECT (SELECT) AS ..
У меня value правда составной — не одно поле, а куча полей. Но это обходиться джойном.
NB>(groupid, cond, time)
Да, придется такой делать. У меня есть индекс (groupid, time), но его не хватает.
Надеюсь поможет также (cond, groupid, time)? Мне он нужнее
Здравствуйте, Буравчик, Вы писали:
Б>У меня value правда составной — не одно поле, а куча полей. Но это обходиться джойном.
смотря как джоинить. что за база то?
NB>>(groupid, cond, time)
Б>Да, придется такой делать. У меня есть индекс (groupid, time), но его не хватает. Б>Надеюсь поможет также (cond, groupid, time)? Мне он нужнее