2015-09-25 61 views
1

我正在使用PostgreSQL编写一个SQL查询来从两次相同的sql结果中进行选择。例如,Postgresql:如何从sql结果中选择两次

SELECT a.id, b.id 
    FROM 
    (SELECT * FROM tableA) as a, 
    (SELECT * FROM tableA) as b 
    WHERE a.id = b.id+1 

正如你可以看到下面的SQL语句已经执行了两次:

SELECT * FROM tableA 

是否可以暂时代替存储运行相同的查询的SQL结果两次,因为这种查询可以复杂吗?

+0

'tableA'与自身的连接怎么样?例如:'SELECT a.id,b.id from tableA a.id = b.id + 1'上的连接表b b' – Houari

+0

“SELECT * FROM tableA”这行仅仅是一个例子,它可能是复杂的嵌套查询。 – chesschi

+0

如果SELECT * from tableA'不能被视图替换,那么也可以使用[with]的子查询(http://www.postgresql.org/docs/current/static/queries-with .html)关键字 – Houari

回答

3

公共表表达式:

with cte as 
(SELECT * FROM tableA) 
select * from cte where... 

所以你不必写一样的东西两次。不知道它是否执行过一次或严重的时间虽然...

+0

我在想什么(我真的不确定,这似乎是OP的问题):如果您在查询中两次引用CTE,是否保证CTE只会执行一次? – sstan

+0

我不知道,查看执行计划。 – jarlh

1

您可以使用cte

with a as (select * from tableA) 
, b as (select * from tableA) 
select a.id, b.id 
from a join b on a.id = b.id+1 

或者它可以用self-join完成。

select a.id, b.id 
from tableA a join tableB b 
on a.id = b.id+1 
2

CTE解决了您的问题。但它很可能也是lead()函数。 。 。并具有更好的性能:

SELECT a.* 
FROM (SELECT a.id, lead(a.id) over (order by a.id) as b_id 
     FROM tableA a 
    ) a 
WHERE id = b_id; 

或者,对于一些将与重复的工作:

SELECT a.id, a.id + 1 
FROM tableA a 
WHERE EXISTS (SELECT 1 FROM tableA a2 WHERE a2.id = a.id + 1); 

自联接似乎矫枉过正不管你真的想完成的任务。这可能是正确的解决方案,但也有其他选择。