我在MySQL上运行这个查询

SELECT ID FROM (
    SELECT ID, msisdn
    FROM (
        SELECT * FROM TT2
    )
);

它给出了这个错误:

每个派生表必须有自己的别名。

是什么导致了这个错误?


我认为它在要求你这样做:

SELECT ID
FROM (SELECT ID,
             msisdn 
      FROM (SELECT * FROM TT2) as myalias
     ) as anotheralias;

但是为什么要首先编写这个查询呢?


每个派生表(又名子查询)必须有别名。也就是说,括号中的每个查询都必须被赋予一个别名(AS之类的),这个别名可以用来在外部查询的其余部分引用它。

SELECT ID FROM (
    SELECT ID, msisdn FROM (
        SELECT * FROM TT2
    ) AS T
) AS T

当然,在您的情况下,整个查询可以替换为:

SELECT ID FROM TT2

这里有一个不同的例子,没有别名就不能重写(不能GROUP BY DISTINCT)。

假设有一个叫做purchasing的表,它记录了顾客在商店里的购买行为,也就是说,这是一个多对多的表,软件需要知道哪些顾客在不止一家商店里购买过东西:

SELECT DISTINCT customer_id, SUM(1)
  FROM ( SELECT DISTINCT customer_id, store_id FROM purchases)
  GROUP BY customer_id HAVING 1 < SUM(1);

..每个派生表必须有自己的别名。修复:

SELECT DISTINCT customer_id, SUM(1)
  FROM ( SELECT DISTINCT customer_id, store_id FROM purchases) AS custom
  GROUP BY customer_id HAVING 1 < SUM(1);

(注意AS自定义别名)。


我来到这里是因为我想我应该检查一下,如果有足够的答案,在一个语法错误给了我这个错误之后,或者如果我可以自己发布一个答案。

好吧,这里的答案解释了这个错误是什么,所以没有太多要说的,但尽管如此,我还是会用我自己的话给出我的2分:

这个错误是由于使用FROM命令的子查询生成了一个新表。

这就是派生表,因此,它需要有一个别名(实际上是对它的名称引用)。

给定以下假设查询:

SELECT id, key1
FROM (
    SELECT t1.ID id, t2.key1 key1, t2.key2 key2, t2.key3 key3
    FROM table1 t1 
    LEFT JOIN table2 t2 ON t1.id = t2.id
    WHERE t2.key3 = 'some-value'
) AS tt

最后,FROM命令中的整个子查询将生成别名为tt的表,它将具有以下列id、key1、key2、key3。

然后,使用初始SELECT,我们最终从生成的表(tt)中选择id和key1。