简体   繁体   English

SQL:如果满足条件,则选择满足条件的所有行,如果不满足,则仅选择特定的nuber行

[英]SQL: Select all rows that meet a condition if that condition is met, but only a certain nuber rows if it isn't

I have a requirement for an SQL Server 2005 query I need to write and it's stumping me how to accomplish it. 我对我需要编写的SQL Server 2005查询有要求,这使我难以完成它。 I'll simplifiy it quite a bit, but the essence is that, if a client has no billings more recent than a certain date, I need to select up to 3 of that client's most recent billings. 我会简化很多,但本质是,如果客户没有比某个特定日期更新的账单,我需要从该客户的最新账单中选择最多3个。 But if they have billings after that cutoff date, just display any of those billings. 但是,如果他们在该截止日期之后有帐单,则只需显示其中任何帐单即可。

So, if my cutoff date is Jan 1, 2010 and the data I have is as follows: 因此,如果我的截止日期是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

Then I want to select: 然后我要选择:

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

Anyone have any ideas? 有人有想法么? Thanks 谢谢

  1. Rank the rows for every Client by descending BillingDate . BillingDate降序排列每个客户的行。

  2. For every client, output the dates that either: 对于每个客户,输出以下日期之一:

    • are more recent than the cut-off date, or 比截止日期更新,或者

    • belong to the 3 highest-ranked ones. 属于排名最高的3个。

The query: 查询:

;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

You could use UNION ALL to combine the results of two queries: 您可以使用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)

Something like this should solve your problem? 这样的事情应该可以解决您的问题? You can even make this a subselect if u want to 您甚至可以将其作为子选择

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM