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 server 2005-3表难题_Sql_Sql Server 2005 - Fatal编程技术网

SQL server 2005-3表难题

SQL server 2005-3表难题,sql,sql-server-2005,Sql,Sql Server 2005,SQL Server 2005在2000兼容模式下运行 我有三张表:银行、例外和客户;客户可以与任何银行进行交易,例外情况表中与其关联的银行除外。基本上,它们看起来像下面的模式: Banks Exceptions Clients ----- ---------- ------- bkID bkID              clID clID 我的问题是:我如何才能找到

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

我有三张表:银行、例外和客户;客户可以与任何银行进行交易,例外情况表中与其关联的银行除外。基本上,它们看起来像下面的模式:

Banks        Exceptions        Clients
-----        ----------        -------
bkID         bkID              
             clID              clID
我的问题是:我如何才能找到所有客户,他们最多有两家银行允许与他们交易,即不在例外表上,并且这两家银行中的一家是特定的,对所有客户来说都是相同的

另一种重新表述问题的方式是:我如何找到所有拥有一家特定银行的客户?我们可以选择JPM作为例子,最多选择一家其他银行,允许他们与之交易

到目前为止,我已经创建了一个函数来计算给定一个clID有多少银行可用,但是我真的不知道如何添加所有至少有共同JPM的客户的条件

谢谢大家

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
到目前为止,我正在尝试运行的查询:

select *
from 
    (select
        clID,
        dbo.fnGetNbAvailableBanks(clID) cnt
    from
        Clients) t
where t.cnt <= 2
正如您所看到的,因为我只返回带有的客户端,这应该可以工作:

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
您可以使用哈希表,而不是选择括号中的station,以加快查询速度。

这应该可以:

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

您可以使用哈希表,而不是选择括号中的station,以加快查询速度。

我将函数更改为使用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
查询如下:

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

很抱歉没有缩进,我不知道为什么它们没有出现。。。我当然缩进了代码…

我将函数改为使用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
查询如下:

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

很抱歉没有缩进,我不知道为什么它们没有出现。。。我当然缩进了代码…

发布你所有的代码,包括你的函数代码,可能会有帮助,你离正确的解决方案不远。你的设计有缺陷:例外表应该允许使用TradeWith表。谢谢Alex,但是正如你所能想象的那样,现在不由我来更改设计。这是一个遗留系统,需要几个月的回归测试才能改变任何东西。约束通常会培养创造力,不是吗?发布您拥有的任何代码,包括函数代码,可能会有所帮助,而且您离正确的解决方案不远。您的设计存在缺陷:应允许例外表与表进行交易。谢谢Alex,但正如您所想象的,现在不由我来更改设计。这是一个遗留系统,需要几个月的回归测试才能改变任何东西。约束通常会培养创造力,没有瑕疵,优雅,速度相当快,尤其是与我天真的版本相比。谢谢你!完美无瑕、优雅且速度相当快,尤其是与我天真的版本相比。谢谢你!