2016-11-29 25 views
1

我不是一個SQL的傢伙,我用它在過去,很少有一個問題,不能由谷歌解決...但是這次我需要問社區。每個產品返回一個SQL行與價格和最新日期

我有一個名爲「交易」有數據這樣的表的數據庫:

ProdNo | Price | TransactionDate | PurchasedBy | etc..... 
---------------------------------------------------------- 
3STRFLEX | 13.02 | 20162911  | AWC   | ..... 
3STRFLEX | 15.02 | 20162011  | DWC   | ..... 
3STRFLEX | 15.02 | 20160101  | AWC   | ..... 
AFTV2  | 35.49 | 20162708  | AWC   | ..... 
AFTV2  | 29.99 | 20160106  | DWC   | ..... 
AFTV2  | 29.99 | 20160205  | AWC   | ..... 

所需的輸出是:

ProdNo | Price | TransactionDate 
----------------------------------- 
3STRFLEX | 13.02 | 20162911   
AFTV2  | 35.49 | 20162708   

我已經嘗試了寫這個我自己和我結束與SQL是這樣的:

select t.ProdNo, t.TransactionDate as 'LastPurchaseDate', t.Price 
from Transactions t 
inner join (
    select ProdNo, max(TransactionDate) as 'LastPurchaseDate' 
    from Transactions 
    WHERE Price > 0 
    group by ProdNo 
) tm on t.ProdNo = tm.ProdNo and LastPurchaseDate = tm.LastPurchaseDate 

但是在我的數據集中這返回(減少),其中顯示多每個產品

ProdNo | LastPurchaseDate | Price 
3STRFLX | 20120924   | 0.000000 
3STRFLX | 20120924   | 22.000000 
3STRFLX | 20150623   | 0.000000 
3STRFLX | 20150623   | 1.220000 
3STRFLX | 20150623   | 1.222197 

行,以便確認:我想每個產品1行中,無論價格是購買最新的日期,但我需要在返回的數據中的價格。

感謝

+0

這個問題接受了下來投票。但沒有評論,OP沒有辦法解決/解決這個問題。這也使得很難辯論這一點。我看不出有什麼問題。但是,也許我會同意一個評論......按照我的觀點,我已經提出了包括樣本數據,預期產出,原始努力和對問題的明確描述。 –

+0

@ destination-data謝謝。我也沒有看到這個問題,也許我錯過了一些規則或東西 –

回答

6

您可以使用CTE和分級功能PARTITION BY

WITH CTE AS 
(
    select t.ProdNo, t.TransactionDate as 'LastPurchaseDate', t.Price, 
      rn = row_number() over (partition by ProdNo order by TransactionDate desc) 
    from Transactions t 
) 
SELECT ProdNo, LastPurchaseDate, Price FROM CTE WHERE RN = 1 
+0

這似乎工作完美。謝謝!我現在將研究CTE,所以希望我不需要再次提問 –

+0

如果每條'ProdNo'具有相同的'max(TransactionDate)' – HoneyBadger

1

你在正確的軌道上。如果您使用:

select t.ProdNo, t.TransactionDate as 'LastPurchaseDate', t.Price 
from Transactions t 
inner join (
    select ProdNo, max(TransactionDate) as 'LastPurchaseDate' 
    from Transactions 
    WHERE Price > 0 
    group by ProdNo 
) tm on t.ProdNo = tm.ProdNo and t.TransactionDate= tm.LastPurchaseDate 

請注意連接條件的更改。

查詢中發生了什麼:LastPurchaseDate = tm.LastPurchaseDate。只有一列叫做LastPurchaseDate,所以它將它與自己等同起來,這總是正確的。所以你只剩下t.ProdNo = tm.ProdNo,因爲t.ProdNo不是唯一的,你會爲每個t.ProdNo返回多個記錄。

+0

,那麼這將返回任意記錄。不幸的是,這仍然返回多行。感謝您發現,但。 –

+0

@TedJames,啊,我知道,你有更多的一個記錄具有相同的'max(TransactionDate)'。您必須決定要選擇哪些記錄。 'ROW_NUMBER()'可以提供幫助,但它會返回任意記錄。 – HoneyBadger

0

試試這個。通過使用row_number()。

   select * from 
      (
      select 
      T.ProdNo, 
      T.TransactionDate as 'LastPurchaseDate', 
      T.Price,   
      row_number() over (partition by ProdNo order by TransactionDate desc) as rnk 
      from Transactions T 
      )a 
      where rnk='1' 
+1

爲什麼'rnk ='1''? 'ROW_NUMBER()'返回一個'bigint',所以'rnk = 1'更有意義。 – HoneyBadger

+0

@HoneyBadger你也是對的。 –

-1
SELECT A.ProdNo ,Price ,A.TransactionDate,PurchasedBy 
FROM #Transactions 
JOIN 
(
SELECT ProdNo,MAX(TransactionDate) TransactionDate 
FROM #Transactions 
GROUP BY ProdNo 
)A ON A.TransactionDate = #Trans.TransactionDate 
1

一種方法是使用ROW_NUMBER windowed function

我的查詢使用common table expression (CTE)來提供樣本數據。使用這種技術時,你總是需要一個CTE,或者subquery。這是因爲在SELECT子句中生成的值不能用於WHERE子句。這是一個叫做Logical Processing Order的結果。換一種說法; SQL Server在過濾數據後生成行號。 CTEs /子查詢爲您提供了第二個WHERE子句,即在生成行號後執行操作**。

-- Returning the most recent record from a transaction table. 
WITH SampleDate AS 
    (
     SELECT 
      ROW_NUMBER() OVER (PARTITION BY ProdNo ORDER BY TransactionDate DESC) AS Rn, 
      * 
     FROM 
      (
       VALUES      
        ('3STRFLEX', 13.02, '20162911', 'AWC '), 
        ('3STRFLEX', 15.02, '20162011', 'DWC '), 
        ('3STRFLEX', 15.02, '20160101', 'AWC '), 
        ('AFTV2' , 35.49, '20162708', 'AWC '), 
        ('AFTV2' , 29.99, '20160106', 'DWC '), 
        ('AFTV2' , 29.99, '20160205', 'AWC ') 
      ) AS x(ProdNo, Price, TransactionDate, PurchasedBy) 
    ) 
SELECT 
    * 
FROM 
    SampleDate 
WHERE 
    Rn = 1 
; 

**其實這不完全正確。它被稱爲邏輯訂單的原因。 SQL Sever可以/將會以您認爲合適的方式執行您的查詢。但是,無論您的查詢是在物理上執行的,它都會遵守邏輯順序。

0

請試試這個 - - 如果一個ProdNo有兩個相同的最高TransactionDate,將返回兩兩行

select ProdNo,Price,TransactionDate from Transactions t 
where not exists (select 1 from Transactions where ProdNo=t.ProdNo and TransactionDate>t.TransactionDate) 
相關問題