2016-09-12 9 views
0

У меня есть таблица с заказамиSQL Select MIN в подзапрос возвращает несколько записей

+----+-------------+--------+ 
| ID | OrderNumber | CartId | 
+----+-------------+--------+ 
|1 | ABDE45677 | 1  | 
|2 | ABFRTG456 | 2  | 
+----+-------------+--------+ 

One с КОРЗИНА пунктов для каждой корзине (которая принадлежит к заказу)

+----+--------+-----------+ 
| ID | CartId | ProductId | 
+----+--------+-----------+ 
|1 | 1  | 34577  | 
|2 | 1  | 26846  | 
|3 | 2  | 59055  | 
|4 | 3  | 43567  | 
+----+--------+-----------+ 

И один с тележкой пункта события (такие, как 'послал', 'отправлен', 'вернулся', и т.д.)

+----+---------------------+------------+------+ 
| ID | EventDate   | CartItemId | Type | 
+----+---------------------+------------+------+ 
|1 | 2016-07-12 11:54:12 | 1   |1  | 
|2 | 2016-07-12 12:01:12 | 1   |3  | 
|3 | 2016-07-12 10:10:00 | 2   |1  | 
|4 | 2016-07-12 11:00:00 | 2   |2  | 
|5 | 2016-07-13 13:00:00 | 2   |4  | 
|6 | 2016-07-12 12:00:00 | 3   |1  | 
|7 | 2016-07-14 12:30:12 | 3   |2  | 
+----+---------------------+------------+------| 

отношения являются

Orders >hasmany> Carts >hasmany> CartItems >hasmany> CartItemEvents 

Теперь я хочу получить все заказы со столбцом «статус» в конце. Этот столбец должен отображать самое низкое значение «type» всех событий корзины, принадлежащих заказу. Я хочу только получить последнее событие для каждого элемента заказа.

SELECT o.ID, 
     o.OrderNumber, 
     (SELECT MIN(type) FROM CartItemEvents cie WHERE cie.CartItemId=ci.Id 
             AND cie.EventDate= 
             (SELECT MAX(EventDate) FROM CartItemEvents WHERE ci.id=CartItemId)) 
     AS 'status' 
FROM Orders o 
LEFT JOIN CartItems ci on o.CartId=ci.CartId 

К сожалению, я получаю несколько типов для каждого заказа (одного типа для каждого элемента)

+----+-------------+--------+ 
| ID | OrderNumber | Status | 
+----+-------------+--------+ 
|1 | ABDE45677 | 3  | 
|1 | ABDE45677 | 4  | 
|2 | ABFRTG456 | 2  | 
+----+-------------+--------+ 

Похоже, что функция

SELECT MIN(type) 

не имеет никакого эффекта здесь, так как удаление MIN() приносит тот же результат.

Как я могу получить только минимальный тип для каждого заказа? Может быть, у меня слишком много вложенных подзапросов здесь?

+1

Я не думаю, что вы должны оставить join/subquery в этом выборе, но вы должны полностью присоединиться к ним через заказы, данные о картотеках и картотеке - потому что ваш подзапрос не будет фильтровать ваше заявление. –

+0

Я бы посмотрел на внутреннее соединение с min() и присоединил к нему таблицу, аналогичную [this] (http://stackoverflow.com/questions/39382566/dense-rank-ordering/39382601#39382601). Я нахожусь на мобильном телефоне, поэтому не могу дать ответ, но вы можете увидеть сходство –

ответ

0
SELECT o.ID, 
     o.OrderNumber, 
     MIN(SELECT MIN(type) FROM CartItemEvents cie WHERE cie.CartItemId=ci.Id 
             AND cie.EventDate= 
             (SELECT MAX(EventDate) FROM CartItemEvents WHERE ci.id=CartItemId)) 
     AS 'status' 
FROM Orders o 
LEFT JOIN CartItems ci on o.CartId=ci.CartId 
GROUP BY o.ID 
0
SELECT o.ID, 
    o.OrderNumber, 
    (SELECT MIN(type) FROM CartItemEvents cie INNER JOIN CartItems ci on o.CartId=ci.CartId WHERE cie.CartItemId=ci.Id 
            AND cie.EventDate= 
            (SELECT MAX(EventDate) FROM CartItemEvents WHERE ci.id=CartItemId)) 
    AS 'status' 
FROM Orders o 

ли это. Я удалил Left Join в конце и вместо этого сделал Inner Join в подзапросе.