簡體   English   中英

在T-SQL中,如何整理積極和消極的行動以使它們發生?

[英]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;

輸出:

在此處輸入圖片說明

演示在這里:

Rextester

您可以使用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

我將“ BuySell ”兩列合並為一個(= 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM