Home > Blockchain >  Joining tables when a condition is not met - SQL Oracle
Joining tables when a condition is not met - SQL Oracle

Time:07-20

I have below two tables:

enter image description here

enter image description here

~ What I am looking to do: I want to append the Price from Table 2 (t2) to Table 1 (t1), by joining on Quantity and YYYY_MM. Each t2.price was active in a certain time range (t2.Price_Active_Date_From and t2.Price_Active_Date_To), and the t1.Order_Date should fall within this range. When there is no active price at that order date, I want the result to return null.

So the result should look like:

enter image description here

What I have tried below so far, which works to get the Price_Active_At_Order when there is a price at a certain date, but it doesn't work when there's no active price. How to add a condition in the join so this works?:

select distinct
t1.Product_NR,
t1.Customer,
t1.Quantity,
t2.Price as Price_Active_At_Order,
t1.Order_YYYYMM as Order_Date

from Table_1 t1
join Table_2 t2 on t1.Product_NR = t2.Product_NR
                and t1.Quantity = t2.Quantity
                and t1.Order_YYYYMM between t2.Price_Active_Date_From and t2.Price_Active_Date_To

CodePudding user response:

Inner Join returns empty if the matching results are not found. You can handle it on code level for setting null value if empty response has been returned. However in SQL you'll only get empty result.

If you still want to get NULL values you can use LEFT Join that will return the values for the rows not match with the condition as null for the table on the right side of the Join.

Similarly for Right Join.

When using Left Join, Right Join, Full (Outer) Join, it is possible to return NULL value while (inner) join, cross join will not return NULL value.

For understanding purposes you can go through this link for SQL Join: https://www.geeksforgeeks.org/sql-join-set-1-inner-left-right-and-full-joins/

And answer of the below question: https://docs.microsoft.com/en-us/answers/questions/99875/sql-query-full-join-multiple-tables-but-return-nul.html

CodePudding user response:

Using the data from your question the result is a bit different because the order date from tbl_1 for product 10334 and tbl_1 quantity=1 is out of the period in tbl_2, so the resulting price is Null.

WITH
    tbl_1 AS
        (
            Select 10023 "PRODUCT_NR", 'X' "CUSTOMER", 20 "QUANTITY", 202004 "ORDER_DATE" From Dual UNION ALL
            Select 10023 "PRODUCT_NR", 'Y' "CUSTOMER", 10 "QUANTITY", 202203 "ORDER_DATE" From Dual UNION ALL
            Select 10334 "PRODUCT_NR", 'X' "CUSTOMER",  1 "QUANTITY", 202204 "ORDER_DATE" From Dual 
        ),
    tbl_2 AS
        (
            Select 10023 "PRODUCT_NR",   1 "QUANTITY", 100 "PRICE", 202101 "DATE_FROM", 999912 "DATE_TO" From Dual UNION ALL
            Select 10023 "PRODUCT_NR",  10 "QUANTITY", 120 "PRICE", 202101 "DATE_FROM", 999912 "DATE_TO" From Dual UNION ALL
            Select 10023 "PRODUCT_NR",  20 "QUANTITY", 300 "PRICE", 201605 "DATE_FROM", 202001 "DATE_TO" From Dual UNION ALL
            Select 10023 "PRODUCT_NR",  20 "QUANTITY", 250 "PRICE", 202101 "DATE_FROM", 999912 "DATE_TO" From Dual UNION ALL
            Select 10023 "PRODUCT_NR", 100 "QUANTITY", 400 "PRICE", 202101 "DATE_FROM", 999912 "DATE_TO" From Dual UNION ALL
            Select 10334 "PRODUCT_NR",   1 "QUANTITY",  25 "PRICE", 202101 "DATE_FROM", 202111 "DATE_TO" From Dual UNION ALL
            Select 10334 "PRODUCT_NR",   1 "QUANTITY",  30 "PRICE", 202101 "DATE_FROM", 202111 "DATE_TO" From Dual 
        )
SELECT
    t1.PRODUCT_NR "PRODUCT_NR",
    t1.CUSTOMER "CUSTOMER",
    t1.QUANTITY "QUANTITY",
    t2.PRICE "PRICE_AT_ORDER",
    t1.ORDER_DATE "ORDER_DATE"
FROM
    tbl_1 t1
LEFT JOIN
    tbl_2 t2 ON(t2.PRODUCT_NR = t1.PRODUCT_NR And t2.QUANTITY = t1.QUANTITY And t1.ORDER_DATE Between t2.DATE_FROM And DATE_TO)
ORDER BY
    t1.PRODUCT_NR,
    t1.ORDER_DATE
--  
--  R e s u l t
--  
--  PRODUCT_NR CUSTOMER   QUANTITY PRICE_AT_ORDER ORDER_DATE
--  ---------- -------- ---------- -------------- ----------
--       10023 X                20           Null     202004 
--       10023 Y                10            120     202203 
--       10334 X                 1           Null     202204

As you can see, all that should be done is change your JOIN into LEFT JOIN. Join (Inner Join) returns no rows when condition has no match. Regards...

  • Related