当一个查询是另一个查询的条件时,称之为子查询。子查询可以使用几个简单命令构造功能强大的复合命令。子查询最常用于SELECT-SQL命令的WHERE子句中。子查询是一个 SELECT 语句,它嵌套在一个 SELECT、SELECT…INTO 语句、INSERT…INTO 语句、DELETE 语句、或 UPDATE 语句或嵌套在另一子查询中。

需要用到的表:

account表

any mysql子查询 mysql的子查询_嵌套

borrower表

any mysql子查询 mysql的子查询_子查询_02

branch表

any mysql子查询 mysql的子查询_嵌套_03

customer表

any mysql子查询 mysql的子查询_子查询_04

depositor表

any mysql子查询 mysql的子查询_子查询_05

loan表

any mysql子查询 mysql的子查询_嵌套_06


1.嵌套在where中

a.
操作:找出所有同时在本银行中有账号且有贷款的用户名

SQL

SELECT DISTINCT
    customer_name
FROM
    borrower
WHERE
    customer_name IN (
        SELECT
            customer_name
        FROM
            depositor
    );

结果:

any mysql子查询 mysql的子查询_any mysql子查询_07

事实上这两个表中的确同时又这三个用户

any mysql子查询 mysql的子查询_SQL_08

这里给出另外一种查询方法:

SELECT DISTINCT
    customer_name 
FROM
    borrower 
WHERE
    EXISTS (
        SELECT
            *
        FROM
            depositor
        WHERE
            depositor.customer_name = borrower.customer_name
    );

查询的结果当然是一样的啦。

b.
要找出在”perryridge”支行同时有账户且还有贷款的用户名:

首先我们得找出那个用户在perryridge支行有账户

SQL

SELECT
    customer_name
FROM
    account,
    depositor
WHERE
    account.Account_number = depositor.account_number
AND Branch_name = 'perryridge';

hayes这个用户满足条件:

any mysql子查询 mysql的子查询_SQL_09

这里博主要提醒各位一下在做这个查询的时候一定要先将两个表进行自然连接,然后才进行筛选
也就是必须现有

account.Account_number = depositor.account_number

才能有筛选条件
Branch_name = 'perryridge'

否则的话会产生这样结果:不能拿到我们想要的结果

any mysql子查询 mysql的子查询_嵌套_10

接下来就是找出哪些用户在perryridge这个支行有贷款的
SQL:

SELECT
    customer_name
FROM
    borrower,
    loan
WHERE
    borrower.loan_number = loan.loan_number AND branch_name='perryridge';

结果:

any mysql子查询 mysql的子查询_嵌套_11

好了,经过两次查询,我们可以看到满足条件的是用户名为Hayes的用户。那么我们应该如何一步到位拿到查询结果呢?

SQL:

SELECT DISTINCT
    customer_name
FROM
    borrower,
    loan
WHERE
    borrower.loan_number = loan.loan_number
AND branch_name = 'Perryridge'
AND (branch_name, customer_name) IN (
    SELECT
        branch_name,
        customer_name
    FROM
        depositor,
        account
    WHERE
        depositor.account_number = account.account_number
);

看看查询结果:

any mysql子查询 mysql的子查询_SQL_12

看这不是得到了查询结果了嘛

细心的人肯定会注意到,这个子查询并没有指明支行名称,这是为什么呢?
因为查询条件中是三个条件的交集!


2. 嵌套在From中

这种子查询也叫做派生查询(Derived Relations)

类似这样的
需求:

找到平均帐户余额超过1200美元的分支机构的平均帐户余额

SELECT
    branch_name,
    avg_balance 
FROM
    (
        SELECT
            branch_name AS branch_name,
            avg(balance) AS avg_balance
        FROM
            account 
        GROUP BY
            branch_name
    ) AS branch_avg  
WHERE
    avg_balance > 500;

这个SQL语句的意思是:从account这个表中以branch_name来分组,计算每一个分行的平均资产,然后将查询结果重新投影到一个虚拟表(表名叫做branch_avg(branch_name,avg_balance));

查询结果:

any mysql子查询 mysql的子查询_子查询_13

博主现在所接触到的子查询就只有这两大类了,希望对你有所帮助!