Соединение двух таблиц SQL с GROUP BY не дает желаемых результатов - PullRequest
1 голос
/ 23 декабря 2009

Например, у меня есть база данных заказов в магазине и две таблицы в ней - ORDERS и ORDERSTATUS.

Table : orders
--------------------------------------------
OrderID | OrderItems | AddedTimeStamp      |
--------------------------------------------
1       | Apples     | 2009-12-22 13:15:18 |
--------------------------------------------
2       | Bananas    | 2009-12-22 14:15:24 |
--------------------------------------------

Table : orderstatus
--------------------------------------------------------------------
StatusID | OrderID | Status   | AssignedUser | StatusTimestamp     |
--------------------------------------------------------------------
1        | 1       | Received | JohnSmith    | 2009-12-22 14:15:24 |
--------------------------------------------------------------------
2        | 2       | Received | MaryJane     | 2009-12-22 14:15:24 |
--------------------------------------------------------------------
3        | 1       | Process  | JohnSmith    | 2009-12-22 14:15:24 |
--------------------------------------------------------------------
4        | 2       | Process  | MaryJane     | 2009-12-22 14:15:24 |
--------------------------------------------------------------------
5        | 2       | Deliver  | MaryJane     | 2009-12-22 14:15:24 |
--------------------------------------------------------------------

Я выполняю этот SQL-запрос:

SELECT od.orderid, od.orderitems, os.status, os.assigneduser
FROM orders AS od INNER JOIN orderstatus AS os
ON od.orderid = os.orderid
GROUP BY os.orderid
ORDER BY os.orderid ASC

Это возвращает меня:

------------------------------------------------
OrderID | OrderItems | Status   | AssignedUser |
------------------------------------------------
1       | Apples     | Received | JohnSmith    |
------------------------------------------------
2       | Bananas    | Received | MaryJane     |
------------------------------------------------

Что бы я хотел:

------------------------------------------------
OrderID | OrderItems | Status   | AssignedUser |
------------------------------------------------
1       | Apples     | Process  | JohnSmith    |
------------------------------------------------
2       | Bananas    | Deliver  | MaryJane     |
------------------------------------------------

Я довольно новичок в запросах MySQL, но последние четыре часа бьюсь головой - может кто-нибудь помочь ?? ТИА.

РЕДАКТИРОВАТЬ: Основная цель - я хочу показать последний статус для заказов.

Ответы [ 3 ]

3 голосов
/ 23 декабря 2009

Использование:

   SELECT o.orderid,
          o.orderitems,
          os.status,
          os.assigneduser
     FROM ORDERS o
LEFT JOIN ORDERSTATUS os ON os.orderid = o.orderid
     JOIN (SELECT os.orderid,
                  MAX(os.statustimestamp) 'm_statustimestamp'
             FROM ORDERSTATUS os
         GROUP BY os.orderid) x ON x.orderid = o.orderid
                               AND x.m_statustimestamp = os.status_timestamp

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

Если вы нормализуете свой столбец ORDERSTATUS.status в отдельной таблице (скажем, ORDER_STATUS_CODE, с двумя столбцами - кодом и описанием), вам будет легче, поскольку, предполагая использование целочисленного ключа, вы можете использовать MAX () или MIN () в зависимости от того, как был настроен столбец, чтобы получить наивысший статус для данного заказа.

3 голосов
/ 23 декабря 2009

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

Чтобы сделать это, мы должны сказать MySQL, как выбрать лучшую строку.Посмотрите внимательно ... Как бы вы узнали, если бы вы были машиной, какую строку возвращать?

Лучшее, что я могу догадаться, это то, что вам нужна последняя запись статуса заказа (максимальный статус).Если это так, то вот сценарий, который будет работать:

SELECT
    od.orderid, 
    od.orderitems, 
    os.status, 
    os.assigneduser
FROM orders AS od
INNER JOIN orderstatus AS os ON od.orderid = os.orderid
INNER JOIN (
    SELECT
        MAX(StatusID) AS StatusID,
        OrderId
    FROM orderstatus
    GROUP BY OrderId
) as maxos ON maxos.StatusID = os.StatusID
GROUP BY os.orderid
ORDER BY os.orderid ASC

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

В этом случае вы можете использовать тот же сценарий, описанный выше, но получить максимум (временную метку) вместо максимального (статусный).

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

0 голосов
/ 23 декабря 2009

Похоже, вам нужно знать последний статус и пользователя для заказа. Объединение, группировка и сортировка по не будут работать. Вы можете добиться этого результата несколькими способами, а подзапросы - одним. Попробуйте это:

SELECT od.orderid, od.orderitems, 
(SELECT os.status FROM os.orderstatus AS os WHERE os.orderid = od.orderid ORDER BY os.StatusTimestamp LIMIT 1) AS status, 
(SELECT os.assigneduser FROM os.orderstatus AS os WHERE os.orderid = od.orderid ORDER BY os.StatusTimestamp LIMIT 1) AS assigneduser, 
FROM orders AS od 

Прими это с крошкой соли. Я не знаю, какую версию MySql вы используете, и я больше знаком с Sql Server, чем с MySql. Возможно, вам придется помассировать запрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...