简体   繁体   English

SQL Server 2005-3表难题

[英]SQL server 2005 - 3 table conundrum

SQL Server 2005 running under 2000 compatibility mode. 在2000兼容模式下运行的SQL Server 2005。

I have three tables: Banks , Exceptions and Clients ; 我有三个表: BanksExceptionsClients a client is allowed to trade with any bank except those associated with him on the exceptions table. 客户可以与任何银行进行交易,但exceptions表上与他有关的银行除外。 Basically they look like the below "schema": 基本上,它们看起来像下面的“模式”:

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

My question is: how can I find all the clients that have maximum 2 banks with which they're allowed to trade (ie not on the Exceptions table), and one of those two banks being a specific one, always the same for all clients. 我的问题是:我如何才能找到拥有最多2家允许与其交易的银行的所有客户(即不在“ Exceptions表上),而这两家银行之一是特定银行,对于所有客户来说总是一样的。

An alternate way of rephrasing the question would be: how can I find all the clients that have one specific bank in common (we can choose JPM as an example) and at most one other bank, with which they're allowed to trade? 表述问题的另一种方式是:我如何找到拥有一个共同的特定银行的所有客户(我们可以选择JPM作为示例)以及最多一个可以与之交易的其他银行?

So far I've created a function that counts how many banks are available given a clID , however I can't really figure out how to add that condition of all the clients having at least JPM in common... 到目前为止,我已经创建了一个函数,该函数可以在给定clID计算可用的银行clID ,但是我真的无法弄清楚如何为所有至少具有JPM的客户添加这种条件...

Thanks All! 谢谢大家!

PS: the function code PS:功能码

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

The query as I'm trying to run it so far: 到目前为止我正在尝试运行的查询:

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

As you can see as I only return Clients with <= 2 available banks); 如您所见,我只会退回拥有<= 2个可用银行的客户); I need to further filter them to the ones that also contain JPM among those 2 available banks and I'm asking you as I'm looking for an elegant solution. 我需要进一步筛选它们,使其包含在这两个可用银行中也包含JPM的那些银行,我想在寻找一个优雅的解决方案时问您。

This should work: 这应该工作:

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

You can use hash tables instead select statment in brackets to make this query work faster. 您可以使用哈希表,而不是选择括号中的语句,以使此查询更快地工作。

I changed my function to use EXISTS , like this: 我将函数更改为使用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  

and the query like this: 和这样的查询:

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

Sorry for the lack of indentation, I don't know why they don't show up... I certainly indented the code... 很抱歉缺少缩进,我不知道为什么它们不显示...我当然缩进了代码...

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

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