Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL:如果满足某个条件,则选择所有满足该条件的行,如果不满足该条件,则仅选择一定数量的行_Sql_Sql Server 2005 - Fatal编程技术网

SQL:如果满足某个条件,则选择所有满足该条件的行,如果不满足该条件,则仅选择一定数量的行

SQL:如果满足某个条件,则选择所有满足该条件的行,如果不满足该条件,则仅选择一定数量的行,sql,sql-server-2005,Sql,Sql Server 2005,我需要编写一个SQLServer2005查询,这让我很难完成它。 我将对其进行简化,但实质是,如果客户没有比某个日期更近的账单,我需要从该客户最近的账单中选择最多3个。但如果他们在截止日期之后有账单,只需显示其中的任何账单即可 因此,如果我的截止日期是2010年1月1日,我的数据如下: ClaimID ClientID BillingDate 1 1 March 12, 2010 2 1 June 3, 2010

我需要编写一个SQLServer2005查询,这让我很难完成它。 我将对其进行简化,但实质是,如果客户没有比某个日期更近的账单,我需要从该客户最近的账单中选择最多3个。但如果他们在截止日期之后有账单,只需显示其中的任何账单即可

因此,如果我的截止日期是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
有人有什么想法吗? 谢谢

您可以使用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)
可以使用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)

这样可以解决你的问题吗?如果愿意,您甚至可以将其作为子选择

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)

这样可以解决你的问题吗?如果愿意,您甚至可以将其作为子选择

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)
按降序BillingDate对每个客户机的行进行排序

对于每个客户端,输出以下日期之一:

比截止日期更晚,或

属于排名最高的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
按降序BillingDate对每个客户机的行进行排序

对于每个客户端,输出以下日期之一:

比截止日期更晚,或

属于排名最高的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

您需要显示其中的多少项?全部。如果账单发生在截止日期之后,则显示它。您需要显示其中的多少个?全部。如果账单发生在截止日期之后,则显示它。第二个查询中的NOT EXISTS子句将删除与第一个查询匹配的行。因此,查询可以执行或,但不能同时执行两者。第二个查询中的not EXISTS子句将删除与第一个查询匹配的行。因此,查询既可以执行也可以执行,但不能同时执行。我认为,从OP所说的内容来看,显示所有这些内容是为了应用于截止日期之后发生的所有账单-因此我认为您可以简化查询-删除第二个对排名的引用的内部联接,只需将BillingDate>@CutOffDate或rownum设置在1到3之间即可。@Damien:为什么呢!上面写着:“任何这些账单。”现在简单多了。谢谢你的更正!我想应该是ORDER BY BillingDate DESC。您的查询得到3张最旧的账单。尽管我在描述中明确指出,它应该得到3张最新的账单。。。现在还没有答案吗?哦,好吧。谢谢我认为从OP所说的,显示所有这些都是为了应用于截止日期之后发生的所有账单-因此我认为您可以简化查询-删除对排名第二个引用的内部连接,只需将BillingDate>@CutOffDate或rownum 1到3之间的值应用于排名行。@Damien:为什么!上面写着:“任何这些账单。”现在简单多了。谢谢你的更正!我想应该是ORDER BY BillingDate DESC。您的查询得到3张最旧的账单。尽管我在描述中明确指出,它应该得到3张最新的账单。。。现在还没有答案吗?哦,好吧。谢谢