摘要:

  1. MySQL 语句中 from 部分的子查询

子查询的解释

子查询在 SELECT 语句的 FROM 部分是合法的,实际的语法是:

SELECT … FROM (subquery) [AS] name …

[AS] name 部分是必须的,因为 FROM 部分中的每一个表都必须有一个名字。在子查询中 SELECT 的每一列都必须有一个独一无二的名字。

子查询的例子

一个简单的例子

为了方便演示,我们假设创建了这样的一个表。

1
CREATE TABLE t1(s1 INT, s2 CHAR(5), s3 FLOAT);

然后我们向其中插入了如下的数据:

1
2
INSERT INTO t1 VALUES (1, '1', 1.0)
INSERT INTO t1 VALUES (2, '2', 2.0)

最后我们执行一个如下的查询:

1
2
3
4
5
6
7
8
9
SELECT sb1, sb2, sb3
    FROM (SELECT s1 AS sb1, s2 AS sb2, s3*2 AS sb3 FROM t1) AS sb
    WHERE sb1 > 1;
+------+------+------+
| sb1  | sb2  | sb3  |
+------+------+------+
|    2 | 2    |    4 |
+------+------+------+
1 row in set (0.00 sec)

可以看到这里将子查询的结果构造成一个表 sb,并从中进行第二步的筛选。

从一个表中选出最后几个元素

如果我们想要选出某个表中最后几行怎么办呢,我今天就遇到了这个问题,感觉下面这个子查询的方式最令我满意:

1
2
3
4
SELECT * FROM (
    SELECT * FROM tmp_table ORDER BY id DESC LIMIT 50
    ) sub
    ORDER BY id ASC

在上面的例子中,我们首先在子查询中查询最后50行,但此时查询结果是逆序的。然后我们再在外面的查询中再来重新排序一遍,变成正序排列,此时我们就能获得tmp_table表中的最后50行了。

选出分组求和的平均数

这是 MySQL 官方文档上给出的一个例子,如果我们想要取出分组了的表的一组和的平均值,那么该怎么做呢?首先,这样查询肯定是错误的:

1
SELECT AVG(SUM(column 1)) FROM t1 GROUP BY column1;  -- error

此时我们就可以用到我们的子查询的语法了,我们可以这样写:

1
2
3
SELECT AVG(sum_column1)
    FROM (SELECT SUM(column1) AS sum_column1)
        FROM t1 GROUP BY column1) AS t1;

这里需要注意的是,在子查询中使用的sum_column1列在外部查询中也可以被识别出来。

参考链接: