2012-04-18 41 views
1

我有这样的查询有两种实现方式:为什么UNION ALL有和没有括号表现不一样?

SELECT race1, mode1 
FROM organization 
WHERE condition = 1 LIMIT 1 

UNION ALL 

(SELECT race2, mode2 
FROM organization 
WHERE condition = 1 LIMIT 1) 

UNION ALL 

(SELECT race, mode FROM organization_new 
WHERE PK_Id = 1) 

而且

SELECT race1, mode1 
FROM organization 
WHERE condition = 1 LIMIT 1 

UNION ALL 

SELECT race2, mode2 
FROM organization 
WHERE condition = 1 LIMIT 1 

UNION ALL 

SELECT race, mode FROM organization_new 
WHERE PK_Id = 1 

正如你所看到的,所不同的是仅在第一个查询括号。 在第一个查询中,我得到预期的结果(从所有三个选择中获得所有值,不需要解释)。但是,当我继续与第二个查询,我得到的结果按要求,但不是如预期的,那只是从第一个选择符合WHERE条款的值。也就是说,如果有race1, mode1其中condition = 1,那么我只得到那个结果。如果没有,那么我得到race2, mode2,其中condition = 1。如果第二个select语句是空的,那么我会根据第三个select语句获取值。如果没有提供括号,为什么UNION ALL的行为类似于OR

编辑:我使用MySQL的5.0.51a

+0

您必须对所有查询使用相同的别名ex: - race1作为race,mode1作为 – 2012-04-18 08:34:31

+0

@ sam_13模式,MySQL不需要它,列名将与第一个查询中的名称相同。在这种情况下'race1'和'mode1' .. – nawfal 2013-06-08 06:00:19

回答

2

那是因为你使用的限制。

MySql参考指出,如果你想在单独选择中使用ORDER BY或LIMIT,那么你必须用圆括号包围你的选择。

实施例(从MySQL参考):

由或LIMIT申请ORDER给个体SELECT,放置围绕该括号内的子句SELECT:

(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10) 
UNION 
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10); 

资源可以在这里找到: http://dev.mysql.com/doc/refman/5.0/en/union.html

编辑:更改引用链接,因为前一个是5.5版。但答案没有改变。

+0

好吧,我明白了。我的问题是,如果我不想要所有的联合,但就像它是如何处理我的第二个查询(没有括号)像'OR',我可以安全地继续第二个查询吗? – nawfal 2012-04-18 09:17:13

+0

我的猜测是,这不会是真正有效的MySQL。由于我无法在发布的引用中找到这种行为,以及我的理解如何,因为LIMIT,您的查询的工作方式与此类似。当解析器解析代码时,它会选择数据并看到LIMIT。由于select不在括号中,因此它被理解为查询的结尾(查看引用,其中关于所有UNION的关于LIMIT和ORDER BY的内容在哪里)。如果SELECT为空,它会优化并跳过SELECT到下一个。 要检查这项工作是否尝试更改2.和3.选择地点。然后尝试如果查询可以转到3.如果1.和2.是空的。 – 2012-04-18 09:48:34

+0

@Janis谢谢..是的,它工作,没有太多的测试,我不会问你:)我甚至可以这样做:'(SELECT a FROM t1 WHERE a = 10 AND B = 1 ORDER BY a 10)UNION SELECT a FROM t2 WHERE a = 11 AND B = 2 ORDER BY a LIMIT 10)LIMIT 1;'如原始文档中所述 – nawfal 2012-04-18 09:57:46