SQL server 2005 - 3表难题

时间:2013-05-10 08:46:25

标签: sql sql-server-2005

在2000兼容模式下运行的SQL Server 2005。

我有三个表: Banks Exceptions Clients ;客户可以在 exceptions 表格中与任何银行进行交易,但与他相关的银行除外。基本上它们看起来像下面的“架构”:

Banks        Exceptions        Clients
-----        ----------        -------
bkID         bkID              
             clID              clID

我的问题是:我怎样才能找到所有允许交易最多2家银行的客户(即不在 Exceptions 表上),其中一个这两家银行是特定的银行,对所有客户来说都是一样的。

另一种重新定义问题的方法是:如何找到所有具有一个特定银行的客户(我们可以选择JPM为例),最多只能找到另一家银行, '允许交易?

到目前为止,我已经创建了一个函数来计算给定clID可用的银行数量,但是我无法弄清楚如何添加至少具有{{1}的所有客户端的条件共同的......

全部谢谢!

PS:功能代码

JPM

我正试图运行它的查询到目前为止:

ALTER FUNCTION [dbo].[fnGetNbAvailableBanks](@clientID varchar(10))
RETURNS INTEGER
AS
BEGIN 
declare @intReturn integer

set @intReturn = (select 
                        count(*) numBanks
                    from 
                        Banks fxb
                        left outer join Exceptions bx
                            on bx.clID= @clientID and fxb.bkID = bx.bkID
                    where
                        bx.bkID is null
                        and isnull(fxb.bObsolete, 0) = 0)

RETURN @intReturn 
END

正如您所看到的那样,我只返回具有< = 2个可用银行的客户端);我需要进一步过滤它们到那两个可用银行中也包含JPM的那些,我问你,因为我正在寻找一个优雅的解决方案。

2 个答案:

答案 0 :(得分:1)

这应该有效:

select clID from
(select distinct t1.bkID, t2.clID from Clients t1, Banks t2 
    where t2.bkID not in  
    (select  bkID from  Exceptions t3 where t1.clID = t3.clID ) ) as t1                         
  where clID  not in (select clID from Exceptions where bkID = %yourspecific bankid%)
  group by clID
  having count(*) <= 2

您可以使用哈希表而不是括号中的语句来使此查询更快地运行。

答案 1 :(得分:0)

我将我的功能更改为使用EXISTS,如下所示:

ALTER FUNCTION [dbo].[FNGETNBAVAILABLEBANKS](@clID VARCHAR(10)) 
returns INTEGER 
AS 
  BEGIN 
      DECLARE @intReturn INTEGER 
      SET @intReturn = (SELECT COUNT(*) numBanks 
                        FROM   (SELECT fxb.bkID 
                                FROM   Banks fxb 
                                       LEFT OUTER JOIN Exceptions bx 
                                                    ON bx.clID = @clID 
                                                       AND fxb.bkID = bx.bkID 
                                WHERE  bx.bkID IS NULL 
                                       AND ISNULL(fxb.bObsolete, 0) = 0 
                                       AND EXISTS (SELECT fxb.bkID 
                                                   FROM   Banks fxb 
                                                          LEFT OUTER JOIN 
                                                          Exceptions bx 
                                                                       ON bx.clID = @clID 
                                                                          AND fxb.bkID = bx.bkID 
                                                   WHERE  bx.bkID IS NULL 
                                                          AND fxb.bkID = 'JPM')) a) 
      RETURN @intReturn 
  END  

和这样的查询:

select *
from 
(select
    clID,
    dbo.fnGetNbAvailableBanks(clID) cnt
from
    Clients) t
where t.cnt <= 2 and t.cnt > 0

抱歉缺少缩进,我不知道他们为什么不出现...我当然缩进了代码......