我的UNION SELECT出了什么问题

时间:2011-02-21 02:56:51

标签: sql mysql union

SELECT * 
FROM 
(SELECT Campus_ID AS A_Campus, * FROM A_Campuses
UNION
SELECT Campus_ID AS H_Campus, * FROM H_Campuses
UNION
SELECT Campus_ID AS B_Campus, * FROM B_Campuses)
ORDER BY Campus_Name ASC

它给出了sql错误

  

#1064 - 您的SQL语法出错;检查手册   对应于您的MySQL服务器   用于正确语法的版本   靠近'* FROM A_Campuses UNION   SELECT Campus_ID AS H_Campus,* FROM   第3行的H_Campuses'

4 个答案:

答案 0 :(得分:2)

第1步

您有两个语法错误

  1. 没有别名派生表。
  2. *不能在列名后使用,除非您对源表进行别名
  3. SELECT * 
    FROM 
    (SELECT Campus_ID AS A_Campus, A.* FROM A_Campuses A
    UNION
    SELECT Campus_ID AS H_Campus, H.* FROM H_Campuses H
    UNION
    SELECT Campus_ID AS B_Campus, B.* FROM B_Campuses B) AS X
    ORDER BY Campus_Name ASC
    

    第2步

    但正如菲尔指出的那样,既然你只是要查询订单,那就根本不需要查询。 ORDER BY适用于整个UNION-ed结果。

    SELECT Campus_ID AS A_Campus, A.* FROM A_Campuses A
    UNION
    SELECT Campus_ID AS H_Campus, H.* FROM H_Campuses H
    UNION
    SELECT Campus_ID AS B_Campus, B.* FROM B_Campuses B
    ORDER BY Campus_Name ASC
    

    第3步

    接下来要指出的是,A_,H_和B_必须具有兼容的结构,以便UNION正确对齐。还值得一提的是,将Campus_ID别名为不同的列名称没有任何价值。 UNION结果结果的列名是UNION部分遇到的FIRST名称 - 在这种情况下,所有列名称都来自A_Campuses,以及附加列A_Campus。实际上,您将有两列A_CampusCampus_ID,它们始终保持完全相同的值。你可能想要的是指出数据的来源:(注意我甚至不打算为UNION的第2和第3部分的列别名)

    SELECT 'A' AS Source, A.* FROM A_Campuses A
    UNION ALL
    SELECT 'H', H.* FROM H_Campuses H
    UNION ALL
    SELECT 'B', B.* FROM B_Campuses B
    ORDER BY Campus_Name ASC
    

    注意

    出于性能原因,请使用UNION ALL而不是UNION,它会针对最终结果执行DISTINCT。如果您在不同的表中有重复的Campus_ID,以及完全相同的记录数据,则UNION会导致其中一个被删除,而UNION ALL会保留两个(或所有3个)副本。鉴于添加了Source列,这是不可能的,因此使用UNION ALL将导致更快的查询。

答案 1 :(得分:1)

UNION每个分支中的列通常需要相同的名称,或者最终只有一个名称。此外,子选择需要一个别名(下面的'AS C'),至少在标准SQL中;即使您未在查询中的任何其他位置提及别名,如下所示。

我认为你所追求的可能是:

SELECT * 
  FROM (SELECT "A" AS Campus_ID, * FROM A_Campuses
        UNION
        SELECT "H" AS Campus_ID, * FROM H_Campuses
        UNION
        SELECT "B" AS Campus_ID, * FROM B_Campuses) AS C
 ORDER BY Campus_Name ASC

答案 2 :(得分:0)

可能需要更多括号

SELECT * 
FROM 
(
  (SELECT Campus_ID AS A_Campus, * FROM A_Campuses)
  UNION
  (SELECT Campus_ID AS H_Campus, * FROM H_Campuses)
  UNION
  (SELECT Campus_ID AS B_Campus, * FROM B_Campuses)
)
ORDER BY Campus_Name ASC

你也可以使用不同的列名吗?您可能需要在H_Campus子查询中使用伪A_Campus和B_Campus来获取相同的列。

答案 3 :(得分:0)

这不是你编写联合查询的方式。

任何ORDER BY子句都适用于联合,因此您不需要对其进行子查询。此外,您应该在联合的所有部分中具有相同的列名和别名。您的A_CampusH_CampusB_Campus别名将丢失(不确定哪一个会胜出)。例如

SELECT Campus_ID, Campus_Name FROM A_Campuses
UNION
SELECT Campus_ID, Campus_Name FROM H_Campuses
UNION
SELECT Campus_ID, Campus_Name FROM B_Campuses
ORDER BY Campus_Name ASC

我也不会在联盟中使用SELECT *,因为你需要具体说明你所选择的内容。