简体   繁体   中英

How to select all records from one table that do not exist in another table for certain condition in another table?

All Books Table

CREATE TABLE [dbo].[Book](
    [Id] [uniqueidentifier] NOT NULL,
    [ISBN10] [nvarchar](50) NULL)

Books which a seller has

CREATE TABLE [dbo].[BookSeller](
    [Id] [uniqueidentifier] NOT NULL,
    [ISBN10] [nvarchar](50) NULL,
    [SellerId] int NOT NULL
)

Inserting records in Database Book

 INSERT INTO BOOK (Id, ISBN10)
    VALUES 
    (NEWID(), 'A'),
    (NEWID(), 'B'),
    (NEWID(), 'C'),
    (NEWID(), 'D'),
    (NEWID(), 'E'),
    (NEWID(), 'F'),
    (NEWID(), 'G')
   

Inserting records in Database BookSeller

INSERT INTO [BookSeller] (Id, ISBN10, SellerId)
VALUES 
(NEWID(), 'A', 1),
(NEWID(), 'B', 1),
(NEWID(), 'B', 2),
(NEWID(), 'C', 1),
(NEWID(), 'C', 3),
(NEWID(), 'C', 4),
(NEWID(), 'D', 3),
(NEWID(), 'E', 3),
(NEWID(), 'F', 1),
(NEWID(), 'G', 3)

Book

Id  ISBN10
280C283E-4087-4AFF-9761-358E8F7BC302    A
9FE76BBC-4AB1-436E-8135-2A13FA15CD24    B
C8098DE4-2FC9-4710-B7F9-1D4A92A058CF    C
E48D1CCE-1408-45F6-96BA-7439F56640CC    D
9EF7EFD6-659F-4109-A78A-5CB3E54CDC3E    E
078EB851-945B-4728-9D0F-F45B8A7D742D    F
C33943D5-D01C-480D-BFA5-1B48AA59EDE7    G

BookSeller

Id  ISBN10  SellerId
73CC3266-98CB-426F-AD51-312ADD9CBAF9    A   1
37F09E06-8598-4DB1-9693-F47438B3CB52    B   1
E7A06C9C-8EFC-43F9-A44E-55B5D839B5ED    B   2
A336D899-CA32-47CA-8E39-44F816E08FB0    C   1
11AC0177-9E2D-4AA3-858E-F09C47ACE2E5    C   3
E9A32B1B-66E5-4734-AB87-48FA3D95A34A    C   4
60C0D7CD-6F27-4CEE-A3C5-344542623D87    D   3
E8B00921-1985-4FD2-8024-6D03D55DB869    E   3
1D8A2AF3-512F-4B7E-8857-2279A36F851D    F   1
00E2366E-1478-4408-A265-399E77575714    G   3

I want Books which are not contained by Seller 1 and 3. Other might have. So with current entry no records should be returned but it is returning

Select B.ISBN10 from Book B
LEFT JOIN BookSeller S
ON B.ISBN10 = S.ISBN10
Where SellerId NOT IN (1, 3)

Wrong result

ISBN10
B
C

Ideally no result should have been returned as all books are there for 1 and 3

I want to avoid subquery because subquery with too many records can cause performamnce

You want a not exists ie select all from Book where not exists a record in BookSeller for the same book and SellerId 1 or 3.

select B.ISBN10
from Book B
where not exists (
    select 1
    from BookSeller S
    where B.ISBN10 = S.ISBN10
    and SellerId IN (1, 3)
)

Note - your question title actually gives you the answer:)

Also with regard to your comment about not using sub-queries; you should not restrict your options by premature optimisation as the query engine is usually much better than you might think. I can assure you I have used such a construct on large tables with no issues.

You should always build your queries using the most straightforward logic you can and trust SQL Server to build a good query plan. By trying to optimise yourself you may in fact force a more complex query plan. Of course if you actually do run into performance issues, then its time to dig in an investigate. But you do that scientifically ie by measuring the performance of different options using the execution plan.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM