1

Please see:

http://sqlfiddle.com/#!18/479d1

I have these tables:

CREATE TABLE Item 
(
    OrderNo varchar(10),
    ItemNo varchar(10)
);

CREATE TABLE Order1 
(
    OrderNo varchar(10),
    Month varchar(10)
);

INSERT INTO Item (OrderNo, ItemNo)
VALUES ('111','222'), ('111','333'),
       ('333','444'), ('333','222'), ('333','555'),
       ('444','222'), ('444','555');

INSERT INTO Order1 (OrderNo, Month)
VALUES ('111','Feb'), ('333', 'Jan'), ('444', 'May');

I am looking to return orders which don't have the item '555'. I figured this would be a subquery, but I just cant seem to get it right.

I have tried:

SELECT 
    O.[OrderNo],
    O.[Month],
    I.[ItemNo]
FROM 
    Order1 O
JOIN 
    Item I ON O.[OrderNo] = I.[OrderNo]
WHERE 
    O.[OrderNo] IN (SELECT I.[OrderNo]
                    FROM Item I
                    GROUP BY I.[OrderNo], I.[ItemNo]
                    HAVING I.[ItemNo] <> '555')

Which returns this result:

| OrderNo | Month | ItemNo |
|---------|-------|--------|
|     111 |   Feb |    222 |
|     111 |   Feb |    333 |
|     333 |   Jan |    444 |
|     333 |   Jan |    222 |
|     333 |   Jan |    555 |
|     444 |   May |    222 |
|     444 |   May |    555 |

But in this case I want to remove all orders with item '555', so a result that looks like:

| OrderNo | Month | ItemNo |
|---------|-------|--------|
|     111 |   Feb |    222 |
|     111 |   Feb |    333 |
Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
Ryan Gadsdon
  • 2,272
  • 4
  • 31
  • 56
  • Possible duplicate of [SELECT \* WHERE NOT EXISTS](https://stackoverflow.com/questions/915643/select-where-not-exists) – jose_bacoy Apr 19 '18 at 11:02

4 Answers4

1

You just need to reverse your thinking - you want the ones NOT in the list of orders with a 555.

SELECT 
O.[OrderNo],
O.[Month],
I.[ItemNo]
FROM Order1 O
JOIN Item I ON O.[OrderNo] = I.[OrderNo]
WHERE O.[OrderNo] NOT IN
( SELECT I.[OrderNo]
FROM Item I
WHERE I.[ItemNo] = '555')

http://sqlfiddle.com/#!18/479d1/20

Andrew
  • 26,629
  • 5
  • 63
  • 86
1

How about a simple subquery without grouping? Simply change IN to NOT IN, change the condition from <> '555' to = '555', and remove the grouping:

SELECT O.[OrderNo], O.[Month], I.[ItemNo]
FROM Order1 O
INNER JOIN Item I ON O.[OrderNo] = I.[OrderNo]
WHERE O.[OrderNo] NOT IN (SELECT [OrderNo]
                          FROM Item
                          WHERE [ItemNo] = '555')
Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
0

Just use not exists:

select o.*
from order1 o
where not exists (select 1
                  from items i
                  where i.orderno = o.orderno and i.itemno = 555
                 );

If you want all the items as well as the orders, you can join them in:

select o.*, i.itemno
from order1 o join
     items i
     on o.orderno = i.orderno
where not exists (select 1
                  from items i
                  where i.orderno = o.orderno and i.itemno = 555
                 );
Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
0

Try simple subquery.

Select a.OrderNo, a.Month, b.ItemNo 
From Order1 a  
Inner Join  Item b 
On b.OrderNo = a.OrderNo 
Where a.OrderNo  
Not In (Select OrderNo From Item Where Itemno = '555')
Pravin .Kadam
  • 99
  • 1
  • 7
  • My sincere apology, I was working on query in my SSMS on my machine. Did not refresh the page before posting the answer. did not realize you already posted same. Will delete it once you acknowledge. – Pravin .Kadam Apr 19 '18 at 13:15