Search code examples
sqlsql-serversql-server-2019

Remove duplicate value available in all order


I have a table with values as shown below

Sno orderno partno
101 OCT1 oRing
101 OCT1 Gasket
101 OCT1 Case
101 OCT2 gRing
101 OCT2 Gasket
101 OCT2 Cover
101 OCT3 Case
101 OCT3 Gasket
102 OCT1 Gasket

I want to remove the values that are common in all orders (OCT1,OCT2,OCT3) per Sno. Output should also include orderno as well something like below . Here Gasket is available in all order for 101, so i want to remove it but Case is used in only 2 order out of 3, so i cannot remove it.

Sno orderno partno
101 OCT1 oRing
101 OCT1 Case
101 OCT2 gRing
101 OCT2 Cover
101 OCT3 Case
102 OCT1 Gasket

I have tried below code but not working. Please help/suggest

select * from mytable where partno not in (
select max(partno) from mytable
group by sno
having count(orderno)=count(partno))

Solution

  • We can try the following approach. The first CTE finds the distinct number of orders within each Sno. We then also find, in the second CTE, the number of times a product appears within a given Sno. A matching record is one for which the product did not appear in every order.

    WITH cte1 AS (
        SELECT Sno, COUNT(DISTINCT orderno) AS ordernocnt
        FROM mytable
        GROUP BY Sno
    ),
    cte2 AS (
        SELECT t1.*, t2.ordernocnt,
               COUNT(*) OVER (PARTITION BY Sno, partno) partcnt
        FROM mytable t1
        INNER JOIN cte1 t2 ON t2.Sno = t1.Sno
    )
    
    SELECT Sno, orderno, partno
    FROM cte2
    WHERE partcnt < ordernocnt OR ordernocnt = 1
    ORDER BY Sno, orderno;