【问题标题】:Find all customers who have an account at all branches located in Brooklyn查找在布鲁克林的所有分支机构拥有帐户的所有客户
【发布时间】:2017-03-30 14:24:45
【问题描述】:

我有一些桌子:

“分支”表(分支名称、分支城市、资产)

“客户”表(客户名称、客户街道、客户城市)

“账户”表(account_number、branch_name、balance)

“贷款”表(loan_number、branch_name、amount)

“存款人”表(customer_name、account_number)

“借款人”表(customer_name、loan_number)

现在我想查找在布鲁克林的所有分行都有帐户的所有客户。这是我针对此问题的 SQL。但我想知道如何使用 TABLE JOIN,而不使用 EXCEPT 来解决这个问题。有人可以帮帮我吗?????谢谢。

SELECT distinct S.customer_name FROM depositor as S
WHERE not exists (
     (SELECT branch_name
      FROM branch
      WHERE branch_city = 'Brooklyn')
      EXCEPT
      (SELECT R.branch_name
       FROM depositor as T, account as R
       WHERE T.account_number = R.account_number and
             S.customer_name = T.customer_name ))

【问题讨论】:

  • 这不是和你的另一个问题一样吗?无论如何,我认为您想使用 JOIN 而不是 UNION。您是在尝试了解 UNION 的工作原理还是尝试为查询找到一个好的解决方案?

标签: sql database


【解决方案1】:

我想不出使用UNION 的方法。您的问题是找到在布鲁克林拥有所有分支机构的客户。基本上有两种方法可以解决这个问题。

解决方案 1 - 查找不在布鲁克林拥有所有分支机构的客户。

(故意双重否定)。换句话说,找到所有在布鲁克林没有至少一家分店的客户,然后拿走其余的。

这就是您在示例中所做的。您将布鲁克林的所有分支机构 EXCEPT 客户拥有的分支机构,如果没有布鲁克林分支机构剩余,则客户拥有所有分支机构。您可以使用联接以另一种方式执行此操作,但您的可能更具可读性。

SELECT customer_name
FROM customer
WHERE customer_name NOT IN (
    SELECT d.customer_name
    FROM depositor d
    INNER JOIN branch brooklyn ON brooklyn.branch_city = 'Brooklyn'
    LEFT JOIN account a 
        ON d.account_number = a.account_number
        AND brooklyn.branch_name = a.branch_name 
    WHERE a.account_number IS NULL )

解决方案 2 - 查找在布鲁克林拥有与布鲁克林分支机构数量相同数量的所有客户。

为此,您需要使用GROUP BY 来获取每位客户的布鲁克林分支机构数量,然后您可以使用它与布鲁克林的分支机构总数进行比较。

SELECT d.customer_name
FROM depositor d
INNER JOIN account a ON d.account_number = a.account_number
INNER JOIN branch b ON a.branch_name = b.branch_name
WHERE b.branch_city = 'Brooklyn'
GROUP BY d.customer_name
HAVING COUNT(DISTINCT B.branch_name) = (
    SELECT COUNT(branch_name)
    FROM branch 
    WHERE branch_city = 'Brooklyn')

UNION 用于合并两个数据集。如果您的问题是......

“查找所有拥有布鲁克林分行账户或贷款的客户。”

...那么您可以使用UNION

SELECT DISTINCT d.customer_name
FROM depositor d
INNER JOIN account a ON d.account_number = a.account_number
INNER JOIN branch b ON a.branch_name = b.branch_name
WHERE b.branch_city = 'Brooklyn'
UNION
SELECT DISTINCT l.customer_name
FROM borrower bo
INNER JOIN loan l ON bo.loan_number = l.loan_number
INNER JOIN branch b ON l.branch_name = b.branch_name
WHERE b.branch_city = 'Brooklyn'

【讨论】:

  • 对不起,我的意思是加入。这是我的错误,我纠正了它。我认为您的第二个解决方案就是我所要求的,并且有明确的解释。谢谢
【解决方案2】:
Select A.customer_name
From depositor as A
Left join account as B
on B. account_number = A.account_number
group by A.customer_name
Having count(distinct(B.branch_name))  = 
(select count(branch_name) from branch where branch_city = 'Brooklyn')

【讨论】:

    【解决方案3】:

    假设您想要回答:“查找在布鲁克林的任何分行拥有帐户的所有客户”

    select c.*
    from customer c
    inner join depositor d
       on c.customer_name = d.customer_name
    inner join account a
       on d.account_numver = a.account_number
    inner join branch b
       on a.branch_name = b.branch_name
    where b.branch_city = 'Brooklyn'
    

    如果一个客户可以拥有多个帐户,或者一个帐户可以拥有多个分支机构,则需要调整联接。

    【讨论】:

    • 我认为问题是询问在布鲁克林 all 分行拥有帐户的客户,此解决方案将返回在 any拥有帐户的客户> 布鲁克林分店。
    • @fqhv,我同意这是对问题的可能解读。我以为它要求any。看看OP是否可以澄清会很有趣。我希望不会。
    猜你喜欢
    • 2016-09-15
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多