如何检查sql中的1对多关系

如何检查sql中的1对多关系,sql,Sql,从一个银行领域,我有一个客户和许多与之相关的账户 Client 1 - Account A Client 1 - Account B Client 2 - Account A Client 2 - Account B Client 2 - Account C 在accounts表中,有一个状态标志,我想检查是否为1个客户端的所有帐户设置为“Y” 因此,当一个客户机的所有帐户都将该标志设置为“Y”时,我们通过了测试。 有人知道如何在SQL中检查它吗 我用下面的shell尝试了group by,但

从一个银行领域,我有一个客户和许多与之相关的账户

Client 1 - Account A
Client 1 - Account B
Client 2 - Account A
Client 2 - Account B
Client 2 - Account C
在accounts表中,有一个状态标志,我想检查是否为1个客户端的所有帐户设置为“Y”

因此,当一个客户机的所有帐户都将该标志设置为“Y”时,我们通过了测试。 有人知道如何在SQL中检查它吗

我用下面的shell尝试了group by,但似乎不起作用:

select client_number
from client_table A, account table B
where B.flag = 'Y'
group by client number having count(*) =1
使用
count()>1
并在这两个表之间建立关系。我假设您使用client_number在这两个表之间建立了关系

select A.client_number
from client_table A, account table B
where  A.client_number=B.client_number
group by B.client_number having count(*) >1
试试这个

select client_number
from client_table A, account table B
where B.flag = 'Y' AND B.flag != 'N'
group by client number having count(*) > 0
试试这个

select A.client_number 
from client_table A join account_table B on A.client_number=B.Client_number
where B.flag = 'Y'
group by A.client_number 
having count(*) >1
  • 假设
    account\u表中的
    id列
  • 假设
    client\u表中的
    id\u account
    列为
    account\u表中的
    id
    外键
这是一个ANSI 1992版本,我相信这就是你想要的:

SELECT 
    a.client_number, 
    COUNT(DISTINCT(a.id_account)) AS distinct_accounts,
    COUNT(DISTINCT(IF(ISNULL(b.id), 0, 1))) AS distinct_flagged_accounts
FROM 
    client_table a
        LEFT JOIN account_table b ON a.id_account = b.id AND b.flag = 'Y'
GROUP BY a.client_number 
HAVING COUNT(DISTINCT(a.id_account)) = COUNT(DISTINCT(IF(ISNULL(b.id), 0, 1)))
;

FIDDLE:

我假设您的accounts表包含客户编号,因此这将用于连接表。但是,如果您想要的只是满足此标准的客户编号,那么听起来您只需要检查这一个表,除非您的结果中还需要其他字段,而您没有提到这些字段

HAVING子句将在分组操作后检查结果。我们需要一个组,其中客户端的所有帐户都具有相同的值,如
计数(不同状态)=1所示,其中客户端的最高状态值(在本例中,所有状态值)为“Y”

select client_number
  from account_table
  group by client_number
  having count(distinct status) = 1
     and max(status) = 'Y'
但是,如果它们由一个ID字段连接,那么可能需要使用这两个表,以便从客户机表中获取客户机编号

select client_number
  from client_table
  where client_id in (select client_id
                        from account_table
                        group by client_id
                        having count(distinct status) = 1
                           and max(status) = 'Y'
                     )
SELECT client_name, CASE WHEN NumOfAccts = NumOfY THEN 'Pass' ELSE 'Fail' END PassTest
FROM Clients c INNER JOIN
(
SELECT client_number, COUNT(*) NumOfAccts, SUM(
    CASE WHEN A.Status = 'Y' THEN 1 ELSE 0 END) NumOfY
FROM Accounts A
GROUP BY client_number
) s ON c.client_number = s.client_number;

为了获得我认为您正在寻找的数据,您需要编写两条
SELECT
语句。我对表结构的外观做了一些假设,因此您可能需要调整我使用的一些列名

第一个
选择
设置您想要比较的实际信息。它提供您的所有客户(按其数量)、他们拥有的帐户总数,以及
案例
语句帮助您确定状态为“Y”的帐户数量

SELECT client_number, COUNT(*) NumOfAccts, SUM(
    CASE WHEN A.Status = 'Y' THEN 1 ELSE 0 END) NumOfY
FROM Accounts A
GROUP BY client_number;
这可能足以决定谁通过,谁失败。但是如果您需要一个客户机名称和一个实际的通过/失败文本,我们将使用这个
SELECT
语句作为一个子选择,它将连接回您的客户机表

select client_number
  from client_table
  where client_id in (select client_id
                        from account_table
                        group by client_id
                        having count(distinct status) = 1
                           and max(status) = 'Y'
                     )
SELECT client_name, CASE WHEN NumOfAccts = NumOfY THEN 'Pass' ELSE 'Fail' END PassTest
FROM Clients c INNER JOIN
(
SELECT client_number, COUNT(*) NumOfAccts, SUM(
    CASE WHEN A.Status = 'Y' THEN 1 ELSE 0 END) NumOfY
FROM Accounts A
GROUP BY client_number
) s ON c.client_number = s.client_number;
正如您所看到的,我们返回到客户机表只是为了得到他们的名字。然后我们有另一个
CASE
语句来比较账户数量和状态为yes的账户数量。如果它们相等,我们将输出“Pass”。否则,我们将输出“Fail”


这样就可以了。

删除您的count(*)=1,因为在您的情况下,一个客户有多个帐户不确定它实际上如何为您工作。我看不出你是如何加入你的
client\u表的
account\u表的
给出你的数据库描述的。@cha OP说它不起作用;-)我希望我的评论能作为友好的鼓励,继续努力。一个好的脑筋急转弯通常是一个很好的学习方式。这会忽略任何状态不是“Y”的行,那么你如何知道它们中是否有“N”行?这会忽略任何状态不是“Y”的行,那么你如何知道它们中是否有“N”行?@WarrenT通过删除
B.flag='Y'
编辑了我的答案。然后它会得到所有可用的记录。但是你怎么知道它们是“Y”还是非Y?这会忽略任何状态不是“Y”的行,那么你怎么知道它们中是否有“N”?@WarrenT:谢谢!然后计数条件将变为大于0而不是大于1。因为如果任何客户端只有一个帐户不应跳过。您需要知道至少有1个“Y”和0个帐户不是“Y”。客户端表中有1条记录,5个帐户带有“Y”标志,2个帐户带有“N”标志,那么您的联接将为“Y”帐户返回5行。因此,您不会计算任何带有非Y标志的帐户。@WarrenT,不,这是一个左连接。请参阅sqlfiddle.OK。我没有想到,您的数据模型会在每个客户机上有多个客户机行,每个行都有一个指向不同帐户的密钥。可以想象,银行的“客户”表中每个客户有一行,其中包含有关该客户的信息,可能包括姓名、联系信息、税务id等。由于多个帐户可以属于一个客户机,因此通常会将客户机密钥放在该帐户中,而不是将客户机密钥放在该帐户中。所以,是的,这是一个有效的解决方案,但很可能它不适用于用户的数据库,除非你理解了我遗漏的问题。@WarrenT-hmm根据他的第一个表(
Client 1-Account a
)摘录,我假设他有这个设计,这显然是一个错误的设计,但是,那是他的。现在我想情况可能不是这样。我们需要他的实施的进一步细节。啊,是的,很好。我现在明白怎么可以这样解释了。我只是认为这是列出逻辑关系的简单方法。正如你所说,我们确实需要更多的细节。