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

时间:2013-11-21 05:31:52

标签: sql

从银行业务领域,我有一个客户端和许多与之相关的帐户。

Client 1 - Account A
Client 1 - Account B
Client 2 - Account A
Client 2 - Account B
Client 2 - Account C

在帐户表中,有一个状态标志,我想检查是否为1个客户的所有帐户设置为“Y”。

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

我已尝试使用以下shell进行分组,但似乎无法正常工作:

select client_number
from client_table A, account table B
where B.flag = 'Y'
group by client number having count(*) =1

6 个答案:

答案 0 :(得分:0)

使用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

答案 1 :(得分:0)

试试这个,

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

答案 2 :(得分: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

答案 3 :(得分:0)

  • 假设id
  • 中的列account_table
  • 假设id_account中的client_table列为id
  • account_table的外键

这是我认为你想要的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: http://sqlfiddle.com/#!2/aed84/1

答案 4 :(得分:0)

我假设您的帐户表包含客户端编号,因此这将用于连接表。但如果你想要的只是符合这个标准的客户编号,那么你只需要检查一个表,除非你的结果中还有其他你没有提到的字段。

HAVING子句将在分组操作后检查结果。我们需要一个组,其中客户端的所有帐户具有相同的值,如count(distinct status)=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'
                     )

答案 5 :(得分:0)

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

第一个SELECT为您设置要比较的实际信息。它为您提供所有客户(按其编号),他们拥有的帐户总数,CASE语句可帮助您确定状态为“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_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语句来比较帐户数量和具有“是”状态的帐户数量。如果它们相等,我们将输出'Pass'。否则,我们输出'Fail'。

那应该这样做。