2012-05-19 3 views
0

У меня есть базы данных MySQL со следующей структурой:Сортировка сгруппированных строк в отчете MySQL

Таблица customers:

  • идентификатор (ИНТ)
  • имя (строка)
  • .. .

Таблица orders:

  • идентификатор (целое)
  • CUSTOMERID (интермедиат)
  • timestamp_unix (интермедиат)
  • названия

Теперь я хочу, чтобы выбрать все клиент, а также их последний заказ , Я попробовал следующее заявление:

SELECT a.id, a.name, b.timestamp_unix, b.title FROM customers AS a JOIN orders AS b ON a.id = b.customerID GROUP BY a.id 

Это работает отлично, за исключением, что я не получаю последний порядок (и его название), но первый, который был вставлен в базу данных в качестве первого.

Так как я могу получить последний заказ (самый высокий id и самый высокий timestamp_unix)? Только для метки времени я мог бы просто использовать MAX(b.timestamp_unix), но как мне получить соответствие b.title?

Спасибо!

+0

как насчет того же непосредственно timestamp_unix? последний (самый высокий идентификатор) вставлен на вершине ... что мне не хватает? – DonCallisto

+0

Нет, конечно, это невозможно. В противном случае я бы не стал спрашивать здесь;) Пожалуйста, посмотрите мой комментарий на ответ филлинкля для получения более подробной информации. – caw

+0

Хорошо, поскольку он удалил свой ответ сейчас: просто использование 'ORDER BY' невозможно, так как строки уже сгруппированы при переходе к директиве' ORDER BY', и поэтому MySQL выбирает одну строку каждой группы произвольно. – caw

ответ

3

Вы можете попробовать этот вариант, я проверил его хорошо.

SELECT a.name as 'Customer Name', b.title as 'Order Title' FROM customers a, orders b where a.id=b.customerID AND b.timestamp_unix=(Select max(c.timestamp_unix) from orders c where c.customerID=a.id) GROUP BY a.id

+0

Большое спасибо! Поскольку ваш запрос немного быстрее, ваш самый лучший :) – caw

2
SELECT a.id, a.name, b.timestamp_unix, b.title 
FROM customers AS a 
JOIN ( SELECT customerID, timestamp_unix, title 
     FROM orders 
     ORDER BY timestamp_unix DESC) AS b 
ON a.id = b.customerID 
GROUP BY a.id 
ORDER BY timestamp_unix DESC 

Read this question for more information

Как уже упоминалось в refered вопрос, есть, по крайней мере, 2 подхода к решению этого вопроса. Выберите тот, который вы считаете самым безопасным и простым.

+0

Не должно быть никакой группировки и лимита на подзапрос, чтобы предоставить только последний заказ? – Charleh

+0

Большое спасибо! Это отлично работает, но запрос довольно медленный, не так ли? Он не использует никаких индексов (по крайней мере для меня). Не может ли это быть каким-то образом оптимизировано? – caw

+0

У вас есть какой-нибудь случай? Попробуйте вставить его после 'FROM orders'. И индекс timestamp_unix ускорит это. –

1

Вы должны сделать подвыбор, сделать ваш присоединиться, но взять группировку прочь, а затем сделать это, что вы присоединитесь на

Left join (select orderid from orders where customerid = A.customerid order by orderdate desc limit 1) as lastorder 

Я хотел бы быть более ясным, но я на моем мобильном телефоне хаха

Вот я на моем компьютере сейчас, вот MSSQL скрипку, чтобы показать это - просто преобразовать в Mysql (синтаксис должен быть таким же, кроме ТОП 1 должен быть LIMIT 1 в конце вместо)

http://sqlfiddle.com/#!3/29a3c/13

+0

Большое спасибо! Выглядит неплохо в вашем примере, но MySQL его не поддерживает, к сожалению :('Эта версия MySQL еще не поддерживает 'LIMIT & IN/ALL/ANY/SOME subquery'' – caw

+0

А, должно быть, это версия, уверенный, что он работал в моем sql раньше! О, ну, извините, не смог помочь – Charleh

+0

Нет проблем;) Какую версию вы использовали тогда? 'SELECT VERSION()' возвращает '5.5.22-1 ~ dotdeb.0-log' для меня. – caw

Смежные вопросы