SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 24.02.2009 21:23:52

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Джоин с группировкой

Что-то к вечеру вобще голова не соображает...
Необходимо сделать джоин таблицы по некоторым ключам, но из получившихся записей нужна только последняя запись. Как ограничить? Куда совать группировку поля?

ЗЫ Лимитирование записей не предлагать, покажите как юзать группировку, если подобное вообще возможно без подзапросов smile

Надеюсь, к утру будет ответ и я приступлю дальше к работе big_smile


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#2 24.02.2009 21:39:05

coin
Гуру
Зарегистрирован: 15.07.2008
Сообщений: 66

Re: Джоин с группировкой

Последняя - понятие относительное. Запись может быть последней только если есть сортировка по какому то критерию.
Нужно выбрать всего одну запись из джойна 2ух таблиц или же на каждый ряд первой таблицы присоединять из множества подходящих рядов второй таблицы только один?

P.S. лучше пояснить примером...

Неактивен

 

#3 24.02.2009 22:32:56

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Джоин с группировкой

Второй вариант - на каждый ряд первой таблицы присоединять из множества подходящих рядов второй таблицы только один.

Теперь пример. Есть таблица товаров с ценами в валюте, есть таблица курсов валют к национальной.
Задача. Выбрать цены и показать их как в указанной валюте, так и в национальной. Для этого джоиним таблицу курса. Но курсы меняются, по этому таблица имеет несколько записей пары валют, по сему надо выбрать самый свежий курс (есть поле даты добавления курса).
Вот и получаестя, джоиним по ключам обоих валют, но среди найденных записей нужно выбрать актуальный курс.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#4 24.02.2009 23:55:13

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5831

Re: Джоин с группировкой

select * from t1 left join (select c1, max(c2) c2 from t2 group by c1) t2 on t=c1;

Неактивен

 

#5 25.02.2009 00:05:41

coin
Гуру
Зарегистрирован: 15.07.2008
Сообщений: 66

Re: Джоин с группировкой

У меня чуть посложней получилось:

SELECT `goods`.*,`kurs`.`rate`
FROM `goods`
JOIN
(
  SELECT `rates`.`valuta`,`rates`.`rate`
  FROM
  (
    SELECT `valuta`,MAX(`date`) `date`
    FROM `rates`
    GROUP BY `valuta`
  ) `actual`
  JOIN `rates` ON `rates`.`valuta`=`actual`.`valuta` AND `rates`.`date`=`actual`.`date`
) `kurs` ON `kurs`.`valuta`=`goods`.`valuta`


Таблица `rates` - курсы валют:
`date` - дата
`valuta` (enum) - тип валюты
`rate` - курс
Примари на (`valuta`,`date`).

Отредактированно coin (25.02.2009 00:17:59)

Неактивен

 

#6 25.02.2009 11:53:59

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Джоин с группировкой

Всем спасибо smile Только задача стояла вот:

Neval написал:

если подобное вообще возможно без подзапросов smile

Иначе никак? smile


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#7 25.02.2009 12:59:21

coin
Гуру
Зарегистрирован: 15.07.2008
Сообщений: 66

Re: Джоин с группировкой

Да тут подзапросы то простейшие. Самый внутренний вообще работает только с примари индексом, возвращает несколько пар ключей, которые соответствуют самым актуальным курсам (т.е. если в таблице хранятся только курсы долларов и евро, то будет возвращено 2 ключа валюта/дата). Второй подзапрос выбирает значения курсов для этих примари ключей, соответственно тоже будет возвращено всего 2 записи и уже эти 2 найденные записи будут крепиться к каждому ряду таблицы товаров `goods`. Проще врятли получится.

Неактивен

 

#8 25.02.2009 13:13:02

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Джоин с группировкой

Проблема в том, что мне этот запрос надо на MSSQL состряпать, по сему нужна была собссно логика запроса.
Вот только эта калека не может группировать по не всем полям sad
К примеру, вот MySQL запрос:

select currency, base, rate, MAX(tdate) from currate GROUP BY currency, base

По нему видно, что выбирает уникальные пары валют (currency и base) и выводит значение rate с максимальным tdate.
Но в MSSQL этот запрос не работает, т.к. для поля rate не указана аггрегирующая функция sad Если добавлять группировку и по rate или ставить ему distinct/max/min, то и значения будут неправильные sad Кто-нить в курсе как побороть?


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#9 25.02.2009 13:18:46

coin
Гуру
Зарегистрирован: 15.07.2008
Сообщений: 66

Re: Джоин с группировкой

Neval написал:

Но в MSSQL этот запрос не работает, т.к. для поля rate не указана аггрегирующая функция sad

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

Неактивен

 

#10 25.02.2009 13:24:37

coin
Гуру
Зарегистрирован: 15.07.2008
Сообщений: 66

Re: Джоин с группировкой

С MSSQL не помогу, т.к. даже примерно не представляю что там может помешать выполнится запросу, который я приводил выше, группировка там используется как положено.

Неактивен

 

#11 25.02.2009 13:32:42

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Джоин с группировкой

Там такой финт, что группироваться ОБЯЗАНЫ все поля, которые участвуют в селекте, другого не дано smile По этому не знаю как мне извратиться... наверное придётся группировать данные скриптами, благо сами данные нужны именно скриптам.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#12 25.02.2009 13:36:30

coin
Гуру
Зарегистрирован: 15.07.2008
Сообщений: 66

Re: Джоин с группировкой

SELECT `valuta`,MAX(`DATE`) `DATE`
FROM `rates`
GROUP BY `valuta`


Вот единственный подзапрос с группировкой и он группирует как раз по всем полям SELECT'а, т.е. по полю `valuta`, а для поля `date` использована агрегирующая ф-я, должно работать, проверьте.

Неактивен

 

#13 25.02.2009 13:38:22

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6756

Re: Джоин с группировкой

Ну так поставьте MIN/MAX — должно работать smile

Неактивен

 

#14 25.02.2009 13:54:27

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Джоин с группировкой

Если сделать такой запрос:

SELECT currency, base, MAX(rate), MAX(tdate) FROM currate GROUP BY currency, base

то значения rate и tdate берутся из разных записей, т.е. для каждого поля берётся MAX по всей таблице smile

coin написал:

Вот единственный подзапрос с группировкой и он группирует как раз по всем полям SELECT'а, т.е. по полю `valuta`, а для поля `date` использована агрегирующая ф-я, должно работать, проверьте.

Так - без проблем, а как быть с 4мя полями, если группировка нужна только по двум из них, м? wink

Как я писал, в MySQL запрос работает как надо, а вот в MSSQL уже грабли)))


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#15 25.02.2009 13:56:07

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Джоин с группировкой

Щас попробую сделать джоин на эту же таблицу с ключом по дате)))


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#16 25.02.2009 14:00:36

coin
Гуру
Зарегистрирован: 15.07.2008
Сообщений: 66

Re: Джоин с группировкой

(
  SELECT `rates`.`valuta`,`rates`.`rate`
  FROM
  (
    SELECT `valuta`,MAX(`DATE`) `DATE`
    FROM `rates`
    GROUP BY `valuta`
  ) `actual`
  JOIN `rates` ON `rates`.`valuta`=`actual`.`valuta` AND `rates`.`DATE`=`actual`.`DATE`
)


Весь этот подзапрос с ещё одним вложенным подзапросом и занимается решением этой задачи, самый вложенный выполняет группировку по одному полю и возвращает составной примари ключ (`valuta`,`date`), далее к этому ключу присоединяются остальные поля таблицы.

Неактивен

 

#17 25.02.2009 14:07:25

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Джоин с группировкой

Да, собственно так и сделал, работает, спасибо за подсказки!


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson