使用PostgreSQL将两个选择查询的结果添加到一个表行中

时间:2013-12-05 14:49:47

标签: postgresql stored-procedures concatenation

我试图将两个不同的select语句的结果返回到PostgreSQL中的一行。例如,我有两个返回相同行数的查询:

从table1

中选择tableid1,tableid2,tableid3
+----------+----------+----------+
| tableid1 | tableid2 | tableid3 |
+----------+----------+----------+
|        1 |        2 |        3 |
|        4 |        5 |        6 |
+----------+----------+----------+ 

从table2中选择table2id1,table2id2,table2id3,table2id4

+-----------+-----------+-----------+-----------+
| table2id1 | table2id2 | table2id3 | table2id4 |
+-----------+-----------+-----------+-----------+
|         7 |         8 |         9 |        15 |
|        10 |        11 |        12 |        19 |
+-----------+-----------+-----------+-----------+

现在我想连接这些表,保持相同的行数。我不想加入任何价值观。期望的结果如下所示:

+----------+----------+----------+-----------+-----------+-----------+-----------+
| tableid1 | tableid2 | tableid3 | table2id1 | table2id2 | table2id3 | table2id4 |
+----------+----------+----------+-----------+-----------+-----------+-----------+
|        1 |        2 |        3 |         7 |         8 |         9 |        15 |
|        4 |        5 |        6 |        10 |        11 |        12 |        19 |
+----------+----------+----------+-----------+-----------+-----------+-----------+

我可以对上述两个查询(select * from table1)和(select * from table2)执行以返回上面所需的结果。

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用row_number()进行加入,但我不确定您是否保证行的顺序与表中的顺序保持一致。因此,最好在over()子句中添加一些顺序。

with cte1 as (
   select
       tableid1, tableid2, tableid3, row_number() over() as rn
   from table1
), cte2 as (
   select
       table2id1, table2id2, table2id3, table2id4, row_number() over() as rn
   from table2
)
select *
from cte1 as c1
    inner join cte2 as c2 on c2.rn = c1.rn

答案 1 :(得分:0)

在撰写问题时,你不能拥有自己想要的东西。您的两个SELECT没有任何ORDER BY子句,因此数据库可以按照它的感觉顺序返回行。如果它当前匹配,则只会偶然发生,并且只要您UPDATE一行就会停止匹配。

您需要一个关键列。然后你需要加入关键列。其他任何事情都试图在不实际使用连接的情况下发明不可靠和不安全的连接。

坦率地说,这看起来像是一个非常狡猾的架构。像这样的大量编号整数列,以及连接它们的愿望,可能是你应该使用整数数组或使用具有外键关系的边表的标志。

以其他人想玩的示例数据:

CREATE TABLE table1(tableid1 integer, tableid2 integer, tableid3 integer);
INSERT INTO table1 VALUES (1,2,3), (4,5,6);

CREATE TABLE table2(table2id1 integer, table2id2 integer, table2id3 integer, table2id4 integer);
INSERT INTO table2 VALUES (7,8,9,15), (10,11,12,19);

根据您实际所做的事情,您可能真的需要数组。

我想你可能需要阅读这两篇文章:

解释说SQL表没有订单。因此,您无法按特定顺序获取它们。

请勿使用以下代码,这是危险的,仅作为概念证明包含

碰巧你可以使用set-returns函数hack来非常低效地做你想要的事情。如果没有ORDER BY中的SELECT,它会非常难看并且完全不安全,但我会将其包含在内以保证完整性。我想。

CREATE OR REPLACE FUNCTION t1() RETURNS SETOF table1 AS $$ SELECT * FROM table1 $$ LANGUAGE sql;
CREATE OR REPLACE FUNCTION t2() RETURNS SETOF table2 AS $$ SELECT * FROM table2 $$ LANGUAGE sql;
SELECT (t1()).*, (t2()).*;

如果你在任何真实的代码中使用它,那么小猫会哭。如果表中的行数不同,它会产生疯狂和怪异的结果,并且它会按照最初可能看似正确的顺序生成行,但稍后会随机开始出错。

SANE WAY 是正确添加主键,然后进行连接。