0

テーブルは次のようになります。

tblProducts (約 200k レコード)

SKU,Title,CategoryID
100,Apple,0
101,Orange,0
102,Carrot,1

tblカテゴリー

CategoryID,CategoryName
0,Fruit
1,Vegetables

tblPrices (約 10m レコード)

SKU,BuyPrice,SellPrice,Timestamp
100,1,2,2013-1-1 23:04
100,3,6,2013-1-2 19:04
100,4,8,2013-1-3 21:04
100,4,8,2013-1-4 20:04
100,4,8,2013-1-5 22:04

すべての製品の現在の BuyPrice (tblPrices からの最新のもの) を取得し、NOW() から X 日前の時点での最新の BuyPrice と比較する必要があります。BuyPrice で変更された製品のみが必要です。

これは、「過去 X 日間でどの製品の価格が変化したか?」という質問に答えることができるようにするためです。上記の小さなデータ セットを考えると、1 日または 2 日間は空のテーブルを取得しますが、3 日間は次のように取得します。

SKU,Title,CategoryName,OldBuyPrice,OldSellPrice,NewBuyPrice,NewSellPrice, NBP/OBP
100,Apple,Fruit,       3,          6,           4,          8,            2.00

そして4日間:

SKU,Title,CategoryName,OldBuyPrice,OldSellPrice,NewBuyPrice,NewSellPrice, NBP/OBP
100,Apple,Fruit,       1,          2,           4,          8,            4.00

ネットで同様の解決策を探していましたが、見つかりませんでした。注文は何でもいいです。前もって感謝します!

4

3 に答える 3

1

X日後に日付が最大になる製品を取得するテーブルoldtpcを作成しようとしました。そして、最新の日付の価格を持つ別のnewtpc。そして、「oldtpc」と「newtpc」の間のオン条件で、これらの日付が一致しないことを確認しています

select tp.SKU, tp.Title, tc.CategoryName, oldtpc.BuyPrice, oldtpc.Sellprice, newtpc.buyprice, newtpc.Sellprice
from tblProducts tp
join  tblCategories tc 
on tp.CategoryId= tc.CateogryId
join (select SKU, BuyPrice, SellPrice, max(TimeStamp) as TimeStamp 
             from tblPrices new
             where DATEDIFF ( dd, timestamp, getdate()) < @xdays
             group by SKU, BuyPrice, SellPrice ) as newtpcnewtpc 
on tp.SKU = newtpc .sku 
join (select SKU, BuyPrice, SellPrice, max(TimeStamp) as TimeStamp 
             from tblPrices old 
             where DATEDIFF ( dd, timestamp, getdate()) >= @xdays 
             group by SKU, BuyPrice, SellPrice ) as oldtpc 
on oldtpc.SKU = tp.SKU and oldtpc.timestamp <> newtpc.timestamp

PS:いくつかの構文が間違っているかもしれませんが、一般的な考え方はうまくいくはずだと思います

于 2013-01-04T21:53:58.987 に答える
1

確かに、これは実行可能です。これを行うためのより良い方法がまだあるかもしれませんが、まともなウィンドウ関数バージョンがあります:

WITH Current_Price (sku, buyPrice, sellPrice) as 
                   (SELECT sku, buyPrice, sellPrice
                    FROM (SELECT sku, buyPrice, sellPrice,
                                 ROW_NUMBER() OVER(PARTITION BY sku
                                                   ORDER BY timestamp DESC) as rownum
                          FROM price) t
                    WHERE rownum = 1),

 Price_Back_Previous_Days (sku, buyPrice, sellPrice) as 
                          (SELECT sku, buyPrice, sellPrice
                           FROM (SELECT sku, buyPrice, sellPrice,
                                        ROW_NUMBER() OVER(PARTITION BY sku
                                                         ORDER BY timestamp DESC) as rownum
                                 FROM price
                                 WHERE timestamp < DATEADD(DAY, -3, CONVERT(DATE, GETDATE()))) t
                           WHERE rownum = 1)

SELECT p.sku, p.title, c.categoryName,
       prev.buyPrice as oldBuyPrice, prev.sellPrice as oldSellPrice,
       curr.buyPrice as newBuyPrice, curr.sellPrice as newSellPrice,
       CASE WHEN prev.buyPrice = 0 
            THEN curr.buyPrice
            ELSE 1.0 * curr.buyPrice / prev.buyPrice END as 'NBP/OBP' 
FROM Product p
JOIN Category c
     ON c.categoryId = p.categoryId
JOIN Current_Price curr
     ON curr.sku = p.sku
JOIN Price_Back_Previous_Days prev
     ON prev.sku = p.sku
     AND (prev.buyPrice <> curr.buyPrice
          OR prev.sellPrice <> curr.sellPrice)

これは期待される

SKU  TITLE  CATEGORYNAME  OLDBUYPRICE  OLDSELLPRICE  NEWBUYPRICE  NEWSELLPRICE  NBP/OBP
100  Apple  Fruit         1            2             4            8             4

(作業中のSQL Fiddle ExampleGETDATE()があり、特定の日付が将来の理由に置き換えられています。)

クエリがいつ (日中に) 実行されるかに関係なく、「現在の日付」に対して同じ値を取得しようとしているため、を使用していることに気付くでしょう-3(予想されるように ではありません) 。明らかに、「現在の価格」は変更される可能性があります (ただし、そこにタイムスタンプ パラメータを追加すると修正される可能性があります)。ただし、これにより、特定の日を通して一貫した価格を確認できるようになります。-4

于 2013-01-05T00:49:02.577 に答える
1

これを試してください:SQLフィドル

Select 
   tt.SKU,tt.BuyPrice,tt.SellPrice,tr.BuyPrice As NewBuyPrice,tr.SellPrice As NewSellPrice, tr.BuyPrice/tt.BuyPrice NNBP 
From
(
   select SKU, Max(Timestamps) timestamps
   from t
   Group by t.SKU
) t
Join t tr on t.SKU = tr.SKU AND t.timestamps = tr.Timestamps
Join t tt ON t.SKU = tt.SKU
AND DATEDIFF(D, tt.timestamps, t.timestamps) = 4
AND tt.BuyPrice <> tr.BuyPrice
于 2013-01-04T23:10:11.657 に答える