[英]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
; 我有三个表:
Banks
, Exceptions
和Clients
; 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.