您可以在查询中使用 anEXISTS
或IN
谓词。要么会工作。
(“视图”本质上是一个查询。因此,首先,问题实际上是关于制定返回指定结果集的查询。一旦有了查询,只需将其包装在 CREATE VIEW 语句中即可。我会注意这里我们通常不会在 MySQL 数据库中使用视图。这是因为 MySQL 优化器的工作方式,它总是将视图查询具体化为派生表,这与其他 DBMS 中处理视图查询的方式不同。)
假设您有单独的表customer
,account
和/或loan
,您可能需要EXISTS
谓词、IN
谓词或连接操作,或它们的某种组合。
例如,此查询(如下)使用谓词来测试表和表EXISTS
中是否存在匹配行,并返回在 Perryridge 分行具有至少一个关联帐户和至少一个关联贷款的行。account
loan
customer
SELECT c.name
FROM customer c
WHERE EXISTS ( SELECT 1
FROM account a
WHERE a.customer_id = c.id
AND a.branch = 'Perryridge'
)
AND EXISTS ( SELECT 1
FROM loan l
WHERE l.customer_id = c.id
)
此查询(如下)返回一个等效的结果集,但使用IN
谓词在 account 和 loan 表中查找匹配的行:
SELECT c.name
FROM customer c
WHERE c.id IN ( SELECT a.customer_id
FROM account a
WHERE a.branch = 'Perryridge'
)
AND c.id IN ( SELECT l.customer_id
FROM loan l
)
这个查询(如下)利用 JOIN 操作来查找匹配的行。JOIN 的行为与上面的查询不同,如果在 Perryridge 分行有多个帐户或多个贷款,它将返回客户行的多个副本。GROUP BY
我们可以通过包含一个子句轻松消除这些重复项。
SELECT c.name
FROM customer c
JOIN account a
ON a.customer_id = c.id
AND a.branch = 'Perryridge'
JOIN loan l
ON l.customer_id = c.id
GROUP BY c.id
没有关于您的架构的任何信息,我在这里做了一些假设,即该列id
是表的主键customer
,并且 theaccount
和loan
表都有一个外键customer_id
,customer(id)
等等。
这些查询中的每一个都将表现出不同的性能特征。所有查询都可能受益于索引
... ON account (customer_id, branch)
... ON loan (customer_id)
... ON customer (id, name)
这应该足以回答您的问题。
更新:
给予(比利)
branch(branch_name, branch_city, assets)
customer(customer_name, customer_street, customer_city)
account(account_number, branch_name, balance)
loan(loan_number, branch_name, amount)
depositor(customer_name, account_number)
borrower(customer_name, loan_number)
(这似乎更像是一个学术作业或测试问题,而不是由 IT 专业人员设计和实施的数据库。)
获取在 'Perryridge' 分店depositor
拥有的客户名称 ( ):account
SELECT d.customer_name
FROM depositor d
JOIN account a
ON a.account_number = d.account_number
WHERE a.branch_name = 'Perryridge'
GROUP BY d.customer_name
获取在 'Perryridge' 分店borrower
拥有的客户名称 ( ):loan
SELECT b.customer_name
FROM borrower b
JOIN loan l
ON l.loan_number = b.loan_number
AND l.branch_name = 'Perryridge'
GROUP BY b.customer_name
(如果我们需要表中的其他列customer
,我们将向该表添加一个 JOIN:
SELECT c.customer_name
, c.customer_street
, c.customer_city
FROM customer c
JOIN borrower b
ON b.customer_name = c.customer_name
JOIN loan l
ON l.loan_number = b.loan_number
AND l.branch_name = 'Perryridge'
GROUP
BY c.customer_name
, c.customer_street
, c.customer_city
获取在 'Perryridge' 分行同时拥有存款账户 ( depositor
) 和贷款 ( ) 的客户姓名:borrower
SELECT c.customer_name
, c.customer_street
, c.customer_city
FROM customer c
JOIN borrower b
ON b.customer_name = c.customer_name
JOIN loan l
ON l.loan_number = b.loan_number
AND l.branch_name = 'Perryridge'
JOIN depositor d
ON d.customer_name = c.customer_name
JOIN account a
ON a.account_number = d.account_number
AND a.branch_name = 'Perryridge'
GROUP
BY c.customer_name
, c.customer_street
, c.customer_city
ORDER
BY c.customer_name
, c.customer_street
, c.customer_city
使用带有相关子查询的 EXISTS 谓词的查询可以返回几乎相同的结果集。(不同的是,当客户在 Perryridge 拥有多个账户或多个贷款时,上面的 JOIN 查询可以引入“重复”。那里的 GROUP BY 子句消除了重复。)
SELECT c.customer_name
, c.customer_street
, c.customer_city
FROM customer c
WHERE EXISTS
( SELECT 1
FROM borrower b
WHERE b.customer_name = c.customer_name
AND EXISTS
( SELECT 1
FROM loan l
WHERE l.loan_number = b.loan_number
AND l.branch_name = 'Perryridge'
)
)
AND EXISTS
( SELECT 1
FROM depositor d
WHERE d.customer_name = c.customer_name
AND EXISTS
( SELECT 1
FROM account a
WHERE a.account_number = d.account_number
AND a.branch_name = 'Perryridge'
)
)
ORDER
BY c.customer_name
, c.customer_street
, c.customer_city
此查询不会引入任何重复项,因为它只返回customer
表中的行。(此查询返回重复项的唯一方法是表中是否存在重复行customer
。)如果表中没有重复行customer
,则不需要 GROUP BY。