2011-03-28 37 views
1

我對需要編寫的SQL Server 2005查詢有要求,它困擾着我如何完成它。 我會稍微簡化一下,但其實質是,如果客戶沒有比特定日期更近的帳單,我需要選擇最多3個客戶最近的帳單。但是如果他們在截止日期之後有賬單,只需顯示任何賬單。SQL:如果滿足條件,則選擇符合條件的所有行,但如果不符合,則只選擇某個nuber行

所以,如果我的截止日期是2010年1月1日和我有數據如下:

ClaimID ClientID BillingDate 
1   1   March 12, 2010 
2   1   June 3, 2010 
3   1   January 5, 2008 
4   1   February 9, 2011 
5   1   May 19, 2005 
6   2   November 20, 2005 
7   2   October 5, 2009 
8   3   January 4, 1999 
9   3   July 8, 1997 
10   3   May 7, 2010 
11   3   August 6, 1999 
12   4   May 25, 2000 
13   4   April 1, 2005 
14   4   March 9, 2009 
15   4   December 5, 2007 
16   4   December 19, 1998 
17   4   June 3, 2006 

然後我想選擇:

ClaimID ClientID BillingDate 
1   1   March 12, 2010 
2   1   June 3, 2010 
4   1   February 9, 2011 
6   2   November 20, 2005 
7   2   October 5, 2009 
10   3   May 7, 2010 
14   4   March 9, 2009 
15   4   December 5, 2007 
17   4   June 3, 2006 

人有什麼想法? 感謝

+1

多少的 「任何」 你需要顯示? – 2011-03-28 05:22:27

+0

所有這些。如果計費在截止日期之後發生,則顯示它。 – Luke 2011-03-28 05:45:49

回答

4
  1. 排名爲每個客戶端的行由降BillingDate你甚至可以使這是一個子查詢。

  2. 對於每一個客戶端,輸出的日期,要麼:

    • 比截止日期越近,或

    • 屬於3排名最高的。

查詢:

;WITH ranked AS (
    SELECT 
    *, 
    rownum = ROW_NUMBER() OVER (PARTITION BY ClientID ORDER BY BillingDate DESC) 
    FROM Billings 
) 
SELECT ClaimID, ClientID, BillingDate 
FROM ranked 
WHERE BillingDate > @CutOffDate OR rownum BETWEEN 1 AND 3 
+1

我認爲,根據OP的說法,「顯示所有人」是爲了適用於截止日期之後發生的所有賬單 - 所以我認爲你可以簡化你的查詢 - 刪除內部連接到第二個參考排名,並將BillingDate> @CutOffDate或rownum BETWEEN 1 AND 3'應用於已排序的行。 – 2011-03-28 10:14:13

+0

@Damien:確實如此!它說:'這些*賬單中的任何一個。' *現在很多*更簡單。感謝您的更正! – 2011-03-28 11:22:24

+1

我認爲應該說'ORDER BY BillingDate DESC'。您的查詢獲取3個最舊的賬單。 – Martin 2011-03-28 11:27:50

1

你可以使用UNION ALL的結果結合了兩種查詢:

SELECT * 
FROM MyTable 
WHERE BillingDate > '1-Jan-2010' 

UNION ALL 

SELECT * 
FROM MyTable T1 
WHERE NOT EXISTS (SELECT * 
        FROM MyTable T2 
        WHERE T1.ClientID = T2.ClientID AND T2.BillingDate > '1-Jan-2010') 
AND ClaimID IN (SELECT TOP 3 T3.ClaimID 
       FROM MyTable T3 
       WHERE T1.ClientID = T3.ClientID 
       ORDER BY T3.BillingDate DESC) 
+1

第二個查詢中的NOT EXISTS子句消除了與第一個查詢匹配的行。所以查詢確實做了「或者」並且不*做*「做」。 – srgerg 2011-03-28 05:24:54

0

像這樣的東西應該能解決問題了嗎?如果u想

select ClaimID, ClientID, BillingDate 
from bills 
where BillingDate > @cutoffDate 
UNION ALL 
select ClaimID, ClientID, BillingDate 
from bills a 
where not exists (select 1 from bills b 
     where b.ClientId = a.ClientId 
      and b.BillingDate > @cutoffDate) 
    and 3 >  (select count(1) from bills b 
       where b.ClientId = a.ClientId 
        and b.BillingDate>a.BillingDate) 
相關問題