按列合并两个表

时间:2014-05-01 16:09:51

标签: sql vertica

假设我有两张桌子:

Requested_Products
------------------------------------------
orderId| productId|productDesc   |prodQty
------------------------------------------
order1 | product1 | description1 | 1
order2 | product2 | description2 | 2
order2 | product3 | description3 | 5
order2 | product4 | description4 | 6

Used_Materials
-------------------------------------------
orderId| materialId| materialDesc |matQty
-------------------------------------------
order1 | material1 | description4 | 3
order1 | material2 | description5 | 6
order1 | material3 | description6 | 2
order2 | material4 | description7 | 8

如何通过orderId合并这些表来获取这样的表:

---------------------------------------------------------------------------------
orderId| productId |productDesc   | prodQty | materialId| materialDesc |matQty
---------------------------------------------------------------------------------
order1 | product1  | description1 | 1       | material1 | description4 | 3
order1 | null      | null         | null    | material2 | description5 | 6
order1 | null      | null         | null    | material3 | description6 | 2
order2 | product2  | description2 | 2       | material4 | description7 | 8
order2 | product3  | description3 | 5       | null      | null         | null
order2 | product4  | description4 | 6       | null      | null         | null

我要做的是创建包含所请求项目的单个表格,并使用材料进行订购。我需要此表用于报告目的。

我无法使用JOIN,因为来自Requested_Products和Used_Materials的行无法出现

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

正如已经指出的那样,你需要一个JOIN,但是,我认为你需要一个完整的外连接,而不是已经建议的左连接。

SELECT Requested_Products.*, Used_Materials.*
FROM Requested_Products
FULL OUTER JOIN Used_Materials
ON Requested_Products.orderId = Used_Materials.orderId

答案 1 :(得分:0)

我想我明白你在问什么。单独一个完整的外部不会给你你想要的结果,至少在你的问题中描述。以这种方式查询结果似乎有点不典型,通常我会说在2个查询中提取数据,并在您的工具中单独显示,因为结果中没有显示真实的关系。

然而,为了回答这个问题......

CREATE TABLE Requested_Products (
 orderId      VARCHAR(128)
,productId    VARCHAR(128)
,productDesc  VARCHAR(128)
,prodQty      NUMBER(18)
);

COPY Requested_Products FROM STDIN DELIMITER '|';
order1|product1|description1|1
order2|product2|description2|2
order2|product3|description3|5
order2|product4|description4|6
\.

CREATE TABLE Used_Materials (
 orderId      VARCHAR(128)
,materialId   VARCHAR(128)
,materialDesc VARCHAR(128)
,matQty       NUMBER(18)
);

COPY Used_Materials FROM STDIN DELIMITER '|';
order1|material1|description4|3
order1|material2|description5|6
order1|material3|description6|2
order2|material4|description7|8
\.

\pset null null
SELECT COALESCE(RP.orderId, UM.orderId) AS orderId, productId, productDesc, prodQty, materialId, materialDesc, matQty
FROM ( SELECT X.*, ROW_NUMBER() OVER (PARTITION BY OrderId) Order_Product_Number FROM Requested_Products X ) AS RP
FULL OUTER JOIN
     ( SELECT X.*, ROW_NUMBER() OVER (PARTITION BY OrderId) Order_Material_Number FROM Used_Materials X ) AS UM
ON   ( RP.orderId = UM.orderId AND RP.Order_Product_Number = UM.Order_Material_Number );

 orderId | productId | productDesc  | prodQty | materialId | materialDesc | matQty
---------+-----------+--------------+---------+------------+--------------+--------
 order1  | product1  | description1 |       1 | material1  | description4 |    3
 order1  | null      | null         |    null | material2  | description5 |    6
 order1  | null      | null         |    null | material3  | description6 |    2
 order2  | product2  | description2 |       2 | material4  | description7 |    8
 order2  | product3  | description3 |       5 | null       | null         | null
 order2  | product4  | description4 |       6 | null       | null         | null
(6 rows)

至于什么和为什么......你必须使用FULL OUTER来确保连接两侧的所有行都被拉入。但是你不想要扇出。为此,我们将使用由orderId分区的ROW_NUMBER()生成的序列来排列数据。这将创建一个在orderId更改时重置的数字,以便我们可以加入它。您可能决定以某种方式对序列进行排序,并且可以在partition by子句中执行此操作。最后,因为对于任一个表,orderId可能为null,并且您使用的是FULL OUTER,所以必须COALESCE以确保始终显示非空值。

这可能不会有效。我觉得我能给你一把霰弹枪并瞄准你的脚。我只需要假设你知道自己在做什么,从另一个方向看,然后把手指放在耳朵里。