2011-03-28 41 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) 
相关问题