2013-03-13 2 views
3

Я использую SQL Server 2012. У меня есть две таблицы для хранения заказов на продукты. Заказ, который имеет полученную дату и OrderItem, который имеет идентификатор цены и заказа fk.SQL sub select if exists

Я пытаюсь написать запрос, получить все заказы в диапазоне дат, сгруппировать их по дате, а затем суммировать всю стоимость позиций заказа, чтобы получить общее количество всех заказов на эту дату.

У меня этот рабочий. Теперь я хочу добавить еще один столбец, чтобы выбрать разницу между общей ценой за этот день и 7 дней назад. Если заказов нет 7 дней назад, то столбец должен быть нулевым.

Так что в данный момент у меня есть ниже запрос:

select cast(o.ReceivedDate as date) as OrderDate, 
coalesce(count(orderItems.orderId), 0) as Orders, 
coalesce(sum(orderItems.Price), 0) as Price 
from [Order] o 

left outer join (
     select o.Id as orderId, sum(ot.Price) as Price 
     from OrderItem ot 
     join [Order] o on ot.OrderId = o.Id 
     where o.ReceivedDate >= @DateFrom and o.ReceivedDate <= @DateTo 
     group by o.Id 
) as orderItems on o.Id = orderItems.orderId 

where o.ReceivedDate >= @DateFrom and o.ReceivedDate <= @DateTo 
group by cast(o.ReceivedDate as date) 
order by cast(o.ReceivedDate as date) desc 

Так как я могу добавить мой другой столбец этого запроса? Мне нужно сделать что-то вроде:

//pseudo 
if o.RecievedDate - 7 exists then orderItems.Price - Price from 7 days ago else null 

Но я не уверен, как это сделать? Я создал sqlfiddle, чтобы помочь объяснить http://sqlfiddle.com/#!6/8b837/1

Так из моих образцов данных, что я хочу достичь, это приводит, как это:

| ORDERDATE | ORDERS | PRICE | DIFF7DAYS | 
--------------------------------------------- 
| 2013-01-25 |  3 | 38 |   28 | 
| 2013-01-24 |  1 | 12 |  null | 
| 2013-01-23 |  1 | 10 |  null | 
| 2013-01-22 |  1 | 33 |  null | 
| 2013-01-18 |  1 | 10 |  null | 
| 2013-01-10 |  1 |  3 |   -43 | 
| 2013-01-08 |  2 | 11 |  null | 
| 2013-01-04 |  1 |  1 |  null | 
| 2013-01-03 |  3 | 46 |  null | 

Как вы можете видеть, 25 имеет порядок 7 дней назад, так что показана разница. 24-й номер не отображается так.

Любая помощь будет высоко оценена.

ответ

2

Не уверен, почему вы используете left outer join между [Orders] столом и the subquery, как не может быть заказы без элементов порядка (в целом):

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

SQL-FIDDLE-DEMO

;with cte as (
    select convert(date,o.ReceivedDate) orderDate, 
     count(distinct o.Id) as Orders, 
     coalesce(sum(ot.Price),0) as Price 
    from OrderItem ot 
     join [Order] o on ot.OrderId = o.Id 
    where o.ReceivedDate >= @DateFrom and o.ReceivedDate <= @DateTo 
    group by convert(date,o.ReceivedDate) 
) 
select c1.orderDate, c1.Orders, c1.Price, c1.Price-c2.Price DIFF7DAYS 
from cte c1 left join cte c2 on dateadd(day,-7,c1.orderdate) = c2.orderdate 
order by c1.orderdate desc 


| ORDERDATE | ORDERS | PRICE | DIFF7DAYS | 
------------------------------------------- 
| 2013-01-25 |  3 | 38 |  28 | 
| 2013-01-24 |  1 | 12 | (null) | 
| 2013-01-23 |  1 | 10 | (null) | 
| 2013-01-22 |  1 | 33 | (null) | 
| 2013-01-18 |  1 | 10 | (null) | 
| 2013-01-10 |  1 |  3 |  -43 | 
| 2013-01-08 |  2 | 11 | (null) | 
| 2013-01-04 |  1 |  1 | (null) | 
| 2013-01-03 |  3 | 46 | (null) | 
+1

Ох! Самые сложные! – flup

1

Используйте временную таблицу и присоедините ее к дате.

DECLARE @DateFrom datetime 
SET @DateFrom = '2012-12-02' 

DECLARE @DateTo datetime 
SET @DateTo = '2013-03-13' 

CREATE TABLE #temp (orderdate date, orders int, price money) 
INSERT INTO #temp 
SELECT cast(o.ReceivedDate AS date) AS OrderDate, 
coalesce(count(orderItems.orderId), 0) AS Orders, 
coalesce(sum(orderItems.Price), 0) AS Price 
FROM [Order] o 

LEFT OUTER JOIN (
SELECT o.Id AS orderId, sum(ot.Price) AS Price 
FROM OrderItem ot 
JOIN [Order] o ON ot.OrderId = o.Id 
WHERE o.ReceivedDate >= @DateFrom AND o.ReceivedDate <= @DateTo 
GROUP BY o.Id 
) AS orderItems ON o.Id = orderItems.orderId 

WHERE o.ReceivedDate >= @DateFrom AND o.ReceivedDate <= @DateTo 
GROUP BY cast(o.ReceivedDate AS date) 

SELECT t1.orderdate, t1.orders, t1.price, 
t1.price - t2.price AS diff7days 
FROM #temp t1 LEFT JOIN #temp t2 
ON datediff(DAY, t2.orderdate, t1.orderdate) = 7 
ORDER BY t1.orderdate DESC 

http://sqlfiddle.com/#!6/8b837/34