2008-12-12 39 views
0

我有以下表SQL查詢的建議 - 讓以前的客戶訂單

 
custid ordid qty  datesold 
1   A2  12  2008-01-05 
2   A5  5  2008-01-02 
1   A1  5  2008-01-01 
2   A7  3  2007-02-05 

What't越來越以前爲了讓每一位客戶的最佳方式?

感謝

+0

你有SQL 2005嗎? – 2008-12-12 07:42:17

回答

3

如果「以前的」你的意思是「前的最新一」:

SELECT TOP 1 
    ordid 
FROM 
    orders 
WHERE 
    custid = @custid 
    and datesold < (SELECT MAX(datesold) FROM orders i where i.custid = orders.custid) 
ORDER BY 
    datesold DESC 

中當然datesold必須是一個DATETIME,它具有足夠明確的值來使其工作。只有一個日期是不夠的。例如,如果您創建了一個記錄日期,這將是datesold的一個很好的替代品。

1

對於這類問題的常見方法是選擇馬克斯(datesold),並獲取最新的方式。如果custid/datesold組合是唯一的,這是可以的,但如果在同一天有兩個訂單,它可能會導致重複。

如果您有SQL 2005或更高版本,可以使用ROW_NUMBER函數排名每個客戶的訂單,並選擇每個第一個:

SELECT custid, ordid, qty, datesold 
FROM (
    SELECT *, 
     Row_Number() OVER (PARTITION BY custid ORDER BY datesold desc) as 'Rank' 
    FROM tbl 
) 
WHERE Rank = 1 

,以確保它始終選取相同的項目,即使它們具有相同的dateold,將更多的項目(例如RowID,recieptNumber)添加到Row_number的ORDER BY子句中。

如果你沒有SQL 2005年,通過添加標識列可以做類似的事情:

SELECT custid, ordid, qty, datesold 
FROM tbl 
WHERE id = 
    (SELECT TOP 1 id FROM tbl a WHERE custid = a.custID ORDER BY dateSold) 

這樣做的缺點是會有一個表查找至少爲每一位客戶,如果不是每行。

如果你是幸運的,你想獲得最新的順序來處理,你可以:

SELECT custid, ordid, qty, datesold 
FROM tbl 
INNER JOIN (
    SELECT a.id FROM tbl a GROUP BY tbl.custId 
) s ON tbl.id = s.id 
+0

考慮到只有日期部分存儲在字段中,「ROWNUMBER OVER(... ORDER BY DateSold DESC)」會比「TOP 1 MAX(DateSold)」更加正確或具體嗎?我認爲它會表現相同:給你任何一個匹配的行(第一個按表順序)。 – Tomalak 2008-12-12 08:17:06

+0

取決於DateSold是否是每位客戶唯一的 – 2008-12-18 23:37:15

0

假設:Datesold將是一個升序(以前訂單的日期會比當前更小)

比方說,你想A5之前得到訂單的客戶2.下面是該查詢都可以。

 

SELECT TOP 1 * 
FROM Orders 
WHERE DateSold < (SELECT DateSold FROM Orders WHERE CustId = 2 and OrdID = A5) 
AND CustId = 2 
 
0

這與您詢問的其他問題非常相似。

SELECT 
    T1.ordid 
FROM 
    dbo.Sales T1 
INNER JOIN dbo.Sales T2 ON 
    T2.custid = T1.custid AND 
    T2.datesold > T1.datesold 
LEFT OUTER JOIN dbo.Sales T3 ON 
    T3.custid = T1.custid AND 
    T3.datesold > T1.datesold AND 
    T3.datesold < T2.datesold 
WHERE 
    T1.custid = @custid AND 
    T3.custid IS NULL 

關於具有相同datesold值的行的同樣警告。