[英]In T-SQL, how can I collate positive and negative actions in order that they happened?
我有一張這樣的桌子:
;WITH CTE AS
( SELECT *
FROM (VALUES(1,'BlueCar',NULL),
(2,'RedCar',NULL),
(3,NULL,'BlueCar'),
(4,'GreenCar',NULL),
(5,NULL,'RedCar'),
(6,'BlueCar',NULL)
) AS ValuesTable(Time,Buy,Sell)
)
SELECT *
FROM CTE
Time Buy Sell
1 BlueCar NULL
2 RedCar NULL
3 NULL BlueCar
4 GreenCar NULL
5 NULL RedCar
6 BlueCar NULL
如何查詢此表以獲取仍有庫存的汽車總數? 時間欄是自商店開業以來的天數。 購買汽車的時間必須保留
注意:輸入的數據不會出現庫存中有多輛汽車的情況。
預期產量
Time Buy
4 GreenCar
6 BlueCar
在下面的查詢中,我進行了兩個單獨的匯總,以獲取每輛汽車的購買和出售計數。 我放棄了買入賣出,假設經銷商沒有賣空任何實際上不存在的庫存,那么這不會冒丟失數據的風險。
然后,我將該結果加入CTE,該CTE將為每輛車找到最新時間。 對於每種類型的汽車,這將對應於最新的汽車進入庫存的時間。
我還包括您要求的庫存盤點,但是如果您以后決定擴大查詢范圍,這可能對您很有用。
WITH yourTable AS (
SELECT 1 AS Time, 'BlueCar' AS Buy, NULL AS Sell UNION ALL
SELECT 2,'RedCar',NULL UNION ALL
SELECT 3,NULL,'BlueCar' UNION ALL
SELECT 4,'GreenCar',NULL UNION ALL
SELECT 5,NULL,'RedCar' UNION ALL
SELECT 6,'BlueCar',NULL
),
cte AS (
SELECT Buy, Time
FROM
(
SELECT Buy, Time,
ROW_NUMBER() OVER (PARTITION BY Buy ORDER BY Time DESC) rn
FROM yourTable
) t
WHERE rn = 1
)
SELECT
t1.Buy,
t1.buy_cnt - COALESCE(t2.sell_cnt, 0) AS inventory,
t3.Time
FROM
(
SELECT Buy, COUNT(*) AS buy_cnt
FROM yourTable
GROUP BY Buy
) t1
LEFT JOIN
(
SELECT Sell, COUNT(*) AS sell_cnt
FROM yourTable
GROUP BY Sell
) t2
ON t1.Buy = t2.Sell
LEFT JOIN cte t3
ON t1.Buy = t3.Buy
WHERE
t1.Buy IS NOT NULL AND
t1.buy_cnt - COALESCE(t2.sell_cnt, 0) > 0
ORDER BY
t3.Time;
輸出:
演示在這里:
您可以使用not exists
執行此操作:
;WITH CTE AS
( SELECT *
FROM (VALUES(1,'BlueCar',NULL),
(2,'RedCar',NULL),
(3,NULL,'BlueCar'),
(4,'GreenCar',NULL),
(5,NULL,'RedCar'),
(6,'BlueCar',NULL)
) AS ValuesTable(Time,Buy,Sell)
)
SELECT
[Time], Buy
FROM CTE as T1
WHERE
NOT EXISTS (SELECT 1 FROM CTE as T2 WHERE T2.TIME > T1.TIME AND T1.Buy = T2.Sell) AND
BUY IS NOT NULL
要在某個時間點獲取庫存,您可以做
SELECT car, SUM(Inc) total FROM
(SELECT ID, Buy car, 1 Inc FROM tbl WHERE Buy>''
UNION ALL
SELECT ID, Sell car, -1 Inc FROM tbl WHERE Sell>'') coll
WHERE ID < 20 -- some cut-off time
GROUP BY car
我將“ Buy
和Sell
”兩列合並為一個(= car
),並以每個動作的增量(-1或1)添加另一列( inc
)。 其余的很簡單: group by
[car] group by
select
,然后在inc
列上求和。
這是一個小演示: http : //rextester.com/LLQDW60692
大概,您想要:
with cte as (
. . .
)
select count(buy) - count(sell)
from cte;
注意:這不會驗證您出售的商品是否已經被購買。 它只計算每列中的非NULL
值並取其差。
這是一個好問題。 我喜歡。 您的預期輸出會隨着時間的變化而變化。 請在下面檢查您的問題的簡單查詢。 使用Joins和Rownumber()我們可以實現這一點。
;with CTE as
(
select a.time,a.buy,a.rid,COALESCE(b.rid,0)rid2 ,coalesce(b.sell,a.buy)sell from
( select time,buy,ROW_NUMBER()over( partition by buy order by (select 1)) rid
from #tableName where buy is not null)a left join
( select time,sell, ROW_NUMBER()over( partition by sell order by (select 1)) rid
from #TableName
where sell is not null )b on a.buy=b.sell
)
select Time,Buy from CTE
where rid!=rid2
所有必需的輸出:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.