Domanda

Lets say i have two tables:

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

and

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

How can merge those tables by orderId to get table like this:

---------------------------------------------------------------------------------
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

What i am trying to do is to create single table with requested items and used materials for order. I need this table for reporting purposes.

I cant use JOINs because rows from Requested_Products and Used_Materials cant dublicate

Thanks for help

È stato utile?

Soluzione 2

I think I understand what you are asking. A FULL OUTER alone won't give you the results you are looking for, at least as described in your question. It seems a little atypical to query results this way, and normally I would say to pull the data in 2 queries, and display in your tool separately as there is no real relationship being displayed in your result.

However in the interest of answering the question...

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)

As for what and why... You have to use FULL OUTER to ensure all rows on either side of the join are pulled in. You don't want a fanout, though. To do this, we will line up the data using a sequence generated by the ROW_NUMBER() partitioned by orderId. This will create a number that resets on change of orderId so we can join on it. You may decide you want to order the sequences a certain way, and you can do that in the partition by clause. Finally, because orderId may be null for either table and you are using a FULL OUTER, you must COALESCE to ensure you always show a non-null value.

This probably won't be efficient. I do feel like I'm giving you a shotgun and aiming it at your foot for you. I'll just have to assume you know what you're doing, look the other way, and put my finger in my ears.

Altri suggerimenti

As already pointed out, you need a JOIN, however, I think you need a full outer join, and not a left join, as already suggested.

SELECT Requested_Products.*, Used_Materials.*
FROM Requested_Products
FULL OUTER JOIN Used_Materials
ON Requested_Products.orderId = Used_Materials.orderId
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top