[MySQL] не могу составить запрос

Corrector

Есть таблица продаж
Sales (SaleID, CardNumber, DateTime, ExtraInfo)
Нужно сделать выборку из этой таблицы, в которой по каждому номеру карты (CardNumber) будет только последняя продажа (для сравнения времени продаж используется поле DateTime).
Либо, по другому: нужно оставить в исходной таблице только те записи, для которых нет более поздних продаж с тем же номером карты

0000

Select CardNumber, max(DateTime) from Sales Group By CardNumber

?
Или еще надо получить сопутсвующие SaleID и ExtraInfo?

Corrector

Точно, совсем забыл про Group By. Стал сначала копать в сторону Left Join

hwh2010

Или еще надо получить сопутсвующие SaleID и ExtraInfo?
mysql вроде разрешает включать поля, по которым не группируется, без агрегатных фунций

0000

Разрешает. Но я не сильно MySQL знаю, чтобы гарантировать устойчивый результат. Потому и уточнил.

hprt

А что выведет, если, скажем, к указанному запросу добавить недостающие поля? Что-то мне подсказывает, что бред будет

hwh2010

А что выведет, если, скажем, к указанному запросу добавить недостающие поля? Что-то мне подсказывает, что бред будет
ээ, я тупанул, да, бред
будет произвольная строка, не обязательно та, где максимум достигается

hwh2010

по запросу
select a, max(b c from t group by a

для каждого a будет выдано максимальное b и какое-то c

Vyacha

если нужны и другие поля, то лучше так:

select * from sales s
where not exists (select 1 from sales where cardnumber = s.cardnumber and datetime > s.datetime)

ибо DateTime может повторятся
но в случае повтора вернутся все строки с максимальным DateTime
если всётаки нужна одна запись, то так:
select * from sales s
where not exists (select 1 from sales where cardnumber = s.cardnumber and (datetime > s.datetime or (datetime = s.datetime and saleid > s.saleid

(при условии, что SaleId уникален, конечно)

zya369

mysql вроде разрешает включать поля, по которым не группируется, без агрегатных фунций
людей, которые придумали/разрешили такое имхо нужно вешать за яйца

olegusmaximus

А чем лучше? Разве не будет на каждую запись в таком случае выполнятся подзапрос?
Если нужны остальные поля, то нужно сджойнить полученную выборку с основной таблицей.

Vyacha

людей, которые придумали/разрешили такое имхо нужно вешать за яйца
дане, часто бывает что нужно групбай сделать по первичному ключу, а остальные и так уникальные получаются и выполнять групбай по ним или агрегатную функцию - лишняя работа для субд (пусть и мелкая). так что логика в этом есть. другое дело, что можно налажать с запросом и субд тебя не поправит...
А чем лучше? Разве не будет на каждую запись в таком случае выполнятся подзапрос?Если нужны остальные поля, то нужно сджойнить полученную выборку с основной таблицей.
это если нужны другие поля основной таблицы
а если другие поля тойже (ExtraInfo например)- то сджоинить с самим сабой не получится в данном случае (т.к. нет saleid, а если добавить min(saleid) или max(saleid) - то может вернуться не тот, который соответсвует max(datetime а если добавить saleid в групбай - вернуться тупо все строки)

hprt

Гораздо хуже, когда какой-нить мозг типа кротишки (ничего личного) увидит, что вернулись нужные данные (на примере задачи - соответствующие последней дате) на ЕГО базе и оставит, а потом при реальной эксплуатации внезапно появятся бредовые. Хорошо, если человек, который пишет, понимает, что данные произвольные, но считаю, что лучше явно прописать MIN/MAX (нам ведь пофиг, что, правда?). Эта тема вроде когда-то уже поднималась тут

mbolik1

это если нужны другие поля основной таблицы
а если другие поля тойже (ExtraInfo например)- то сджоинить с самим сабой не получится в данном случае
А чем это не подходит?

select *
from Sales S
join (select CardNumber, max(DateTime) DateTime group by CardNumber) M on (S.CardNumber = M.CardNumber and S.DateTime = M.DateTime)

Или я тебя не правильно понял?

vic-sher

select CardNumber, max(DateTime) DateTime group by CardNumber
Да шурик я от тебя не ожидал
Где таблица? :mad: :mad: :mad:
и я так понял там хотят только одну строку

kokoc88

А чем это не подходит?
Может не подойти, если есть две продажи по одной карте с одним и тем же временем. Уж лучше тогда джойнить по SaleID, судя по всему - это primary key.

Vyacha

я так понял в подзапросе "from sales" пропущен (в майскюле не силен)
тогда:
1. как уже сказали - одну строку не получится
2. джоинить по датетайму не особо хорошо - врятли на нем индекс
3. не факт что так быстрее (даже без учета пункта 2)
4. ну и на мой вкус доставать рекорды без однозначного ключа - при усложнении запроса код может стать трудновоспринимаемым. но это на мой вкус
а в остальном, можно и так
Хорошо, если человек, который пишет, понимает, что данные произвольные, но считаю, что лучше явно прописать MIN/MAX (нам ведь пофиг, что, правда?). Эта тема вроде когда-то уже поднималась тут

ну, собственно, в целом я согласен и это и имел ввиду. лучше всего если бы была агрегатная функция типа FIRST которая брала бы первый попавшийся и её нужно былобы осознано подставлять
зы: темы такой не помню - не часто сюда захожу

rosali

> mysql вроде разрешает включать поля, по которым не группируется, без агрегатных фунций
> нужно вешать
это нужно для ненормализованных таблиц, когда значение этого поля заведомо одинаковое для всех группируемых строчек. ну например в одной колонке хранятся урлы, а в другой хосты этих урлов (чтобы иметь индекс по хосту). тогда в запросе с группировкой по урлу нет ничего криминального в том чтобы попросить заодно и хост.

vic-sher

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