SQL UNION问题

时间:2011-02-17 19:26:26

标签: sql postgresql

有人可以向我解释为什么SQL语句:

SELECT 'TEST1'
UNION SELECT 'TEST2'
UNION SELECT 'TEST3'

返回:

TEST2
TEST3
TEST1

我试图找出这方面UNION关键字背后的逻辑。 有没有办法让它回归:

TEST1
TEST2
TEST3 

不使用ORDER BY子句?换句话说,我可以控制UNION语句的执行顺序吗?

如果重要,我使用Postgre 9.0和PHP作为我的语言

非常感谢, 布雷特

3 个答案:

答案 0 :(得分:6)

根据PostgreSQL docs for UNION

  

UNION有效地将query2的结果追加到query1的结果中(虽然不能保证这是实际返回行的顺序)。

答案 1 :(得分:4)

UNION语义是删除重复项。 PostgreSQL使用Hash函数删除重复项,结果按照键的散列顺序进行输出。

您可以使用UNION ALL,但除非您使用ORDER BY子句,否则SQL仍然不保证订单。

EXPLAIN
SELECT 'TEST1'
UNION SELECT 'TEST2'
UNION SELECT 'TEST3'

产地:

HashAggregate  (cost=0.07..0.10 rows=3 width=0)
  ->  Append  (cost=0.00..0.06 rows=3 width=0)
        ->  Subquery Scan on "*SELECT* 1"  (cost=0.00..0.02 rows=1 width=0)
              ->  Result  (cost=0.00..0.01 rows=1 width=0)
        ->  Subquery Scan on "*SELECT* 2"  (cost=0.00..0.02 rows=1 width=0)
              ->  Result  (cost=0.00..0.01 rows=1 width=0)
        ->  Subquery Scan on "*SELECT* 3"  (cost=0.00..0.02 rows=1 width=0)
              ->  Result  (cost=0.00..0.01 rows=1 width=0)

尽管

EXPLAIN
SELECT 'TEST1'
UNION ALL SELECT 'TEST2'
UNION ALL SELECT 'TEST3'

产地:

Append  (cost=0.00..0.06 rows=3 width=0)
  ->  Subquery Scan on "*SELECT* 1"  (cost=0.00..0.02 rows=1 width=0)
        ->  Result  (cost=0.00..0.01 rows=1 width=0)
  ->  Subquery Scan on "*SELECT* 2"  (cost=0.00..0.02 rows=1 width=0)
        ->  Result  (cost=0.00..0.01 rows=1 width=0)
  ->  Subquery Scan on "*SELECT* 3"  (cost=0.00..0.02 rows=1 width=0)
        ->  Result  (cost=0.00..0.01 rows=1 width=0)

答案 2 :(得分:2)

如果没有order by语句,大多数数据库都不保证任何顺序。

在大多数情况下,

union可以允许数据库并行操作所有3个查询并尽快返回行。