Home > front end >  Joining multiple tables without duplicate rows
Joining multiple tables without duplicate rows

Time:01-05

I have 3 tables as follows

CREATE TABLE tbl1 
(
    [ID] [INT]    NULL,
    [Name] [VARCHAR] (50)   NULL
) ;

CREATE TABLE tbl2 
(
    [ID] [INT]    NULL,
    [TranNo] [VARCHAR] (50)   NULL,
    [TranName] [VARCHAR] (50)   NULL  
) ;    

CREATE TABLE tbl3 
(
    [ID] [INT]    NULL,
    [ResultNo] [VARCHAR] (50)   NULL,
    [ResultName] [VARCHAR] (50)   NULL
) ;    

INSERT INTO tbl1 
VALUES (1,'Andy'), (2,'Lisa')

INSERT INTO tbl2 
VALUES (1, 'A1', 'Order'),
       (1, 'A2', 'Order'),
       (1, 'A3', 'Order'),
       (1, 'A4', 'Delivery'),
       (2, 'A5', 'Order'),
       (2, 'A6', 'Delivery'),
       (2, 'A7', 'Delivery')
 
INSERT INTO tbl3
VALUES (1, 'R1', 'Pending'),
       (1, 'R2', 'Success'),
       (2, 'R3', 'Success')

This is my query

Select 
    tbl1.*,
    tbl2.TranNo, tbl2.TranName, 
    tbl3.ResultNo, tbl3.ResultName
from 
    tbl1
left outer join
    tbl2 on tbl1.ID = tbl2.ID
left outer join
    tbl3 on tbl1.ID = tbl3.ID

Result: sqlfiddle

ID Name TranNo TranName ResultNo ResultName
1 Andy A1 Order R1 Pending
1 Andy A1 Order R2 Success
1 Andy A2 Order R1 Pending
1 Andy A2 Order R2 Success
1 Andy A3 Order R1 Pending
1 Andy A3 Order R2 Success
1 Andy A4 Delivery R1 Pending
1 Andy A4 Delivery R2 Success
2 Lisa A5 Order R3 Success
2 Lisa A6 Delivery R3 Success
2 Lisa A7 Delivery R3 Success

I want a no duplicate result / no extra result like this

ID Name TranNo TranName ResultNo ResultName
1 Andy A1 Order R1 Pending
1 Andy A2 Order R2 Success
1 Andy A3 Order
1 Andy A4 Delivery
2 Lisa A5 Order R3 Success
2 Lisa A6 Delivery
2 Lisa A7 Delivery

or

ID Name TranNo TranName ResultNo ResultName
1 Andy A1 Order R1 Pending
A2 Order R2 Success
A3 Order
A4 Delivery
2 Lisa A5 Order R3 Success
A6 Delivery
A7 Delivery

Thanks for those of you who can help

CodePudding user response:

It looks like you want to zip the transaction (tbl2) and result (tbl3) rows together by ID and a generated row number. Those results can then joined back with tbl1.

Something like:

;WITH CTE_T AS (
    SELECT *, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY TranNo) AS RN
    FROM tbl2
),
CTE_R AS (
    SELECT *, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ResultNo) AS RN
    FROM tbl3
),
CTE_TR AS (
    SELECT
      COALESCE(T.ID, R.ID) AS ID,
      COALESCE(T.RN, R.RN) AS RN,
      T.TranNo, T.TranName, R.ResultNo, R.ResultName
    FROM CTE_T T
    FULL OUTER JOIN CTE_R R
        ON R.ID = T.ID
        AND R.RN = T.RN
)
SELECT A.ID, A.Name, TR.TranNo, TR.TranName, TR.ResultNo, TR.ResultName
FROM tbl1 A
LEFT JOIN CTE_TR TR
    ON TR.ID = A.ID
ORDER BY A.ID, TR.RN

Result:

ID Name TranNo TranName ResultNo ResultName
1 Andy A1 Order R1 Pending
1 Andy A2 Order R2 Succes
1 Andy A3 Order null null
1 Andy A4 Delivery null null
2 Lisa A5 Order R3 Succes
2 Lisa A6 Delivery null null
2 Lisa A7 Delivery null null

See this db<>fiddle>.

Blanks can be inserted in place of nulls by wrapping some of the results with ISNULL(xxx, '').

Eliminating repeated values is best left to the presentation layer, but if you must, you could possibly use CASE expressions that check for RN = 1. Note that ID would need to be converted to a string if you wanted to include blank values in the same column.

See this db<>fiddle.

  • Related