[SQL] Помогите с запросом
От: Буравчик Россия  
Дата: 04.09.19 15:10
Оценка:
Помогите составить SQL запрос

Имеется таблица с полями:
— groupid
— time
— cond
— value

Нужно:
— сгруппировать таблицу по groupid
— в каждой группе отсортировать по time
— в отсортированных записях найти первую запись, удовлетворяющую условию (cond=1)
— получить из этой записи значение value

Повторить для каждой groupid. В итоге хочется получить таблицу с полями
— groupid
— value (для данного groupid, алгоритм извлечения — выше)

P.S. Не смог придумать нормальное название для топика

UPD: СУБД mysql
UPD: Сразу и индексы посоветуйте для быстрого выполнения запроса
Best regards, Буравчик
Отредактировано 04.09.2019 15:12 Буравчик . Предыдущая версия . Еще …
Отредактировано 04.09.2019 15:11 Буравчик . Предыдущая версия .
Re: [SQL] Помогите с запросом
От: biochemist СССР https://www.anekdot.ru/i/caricatures/normal/20/7/27/1595846503.jpg
Дата: 04.09.19 15:22
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Помогите составить 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...
«Национализм во мне столь естественный, что никогда никаким интернационалистам его из меня не вытравить»
Менделеев Д. И.
Re[2]: [SQL] Помогите с запросом
От: Буравчик Россия  
Дата: 04.09.19 15:57
Оценка:
Здравствуйте, 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...


PK может быть, если нужно, пусть будет id.
Best regards, Буравчик
Re[3]: [SQL] Помогите с запросом
От: biochemist СССР https://www.anekdot.ru/i/caricatures/normal/20/7/27/1595846503.jpg
Дата: 04.09.19 17:07
Оценка: 21 (1)
Здравствуйте, Буравчик, Вы писали:

Б>Такая таблица:

Б>[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) — не лучший вариант.
«Национализм во мне столь естественный, что никогда никаким интернационалистам его из меня не вытравить»
Менделеев Д. И.
Re: [SQL] Помогите с запросом
От: night beast СССР  
Дата: 04.09.19 17:48
Оценка: 21 (1)
Здравствуйте, Буравчик, Вы писали:

Б>Нужно:

Б>- сгруппировать таблицу по 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: Сразу и индексы посоветуйте для быстрого выполнения запроса

(groupid, cond, time)
Re[4]: [SQL] Помогите с запросом
От: Буравчик Россия  
Дата: 04.09.19 19:14
Оценка:
Здравствуйте, 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 — тоже куча полей и т.п.
Best regards, Буравчик
Re[2]: [SQL] Помогите с запросом
От: Буравчик Россия  
Дата: 04.09.19 19:52
Оценка:
Здравствуйте, night beast, Вы писали:

NB>
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)? Мне он нужнее
Best regards, Буравчик
Re[3]: [SQL] Помогите с запросом
От: night beast СССР  
Дата: 04.09.19 19:56
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>У меня value правда составной — не одно поле, а куча полей. Но это обходиться джойном.


смотря как джоинить. что за база то?

NB>>(groupid, cond, time)


Б>Да, придется такой делать. У меня есть индекс (groupid, time), но его не хватает.

Б>Надеюсь поможет также (cond, groupid, time)? Мне он нужнее

думаю сработает, но лучше план смотреть по факту
Отредактировано 04.09.2019 19:59 night beast . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.