SQL Server: выберите записи, не связанные с другой таблицей

#sql #sql-server

#sql #sql-server

Вопрос:

У меня есть таблица:

 CREATE TABLE [dbo].[CollectionSite]
(
    [SiteCode] [nvarchar](32) NOT NULL,
    [AddressId] [int] NOT NULL,
    [RemittanceId] [int] NULL,
    // additional columns
)
  

и связанную таблицу:

 CREATE TABLE [dbo].[CollectionSiteAddress]
(
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](255) NULL,
    [Address1] [nvarchar](255) NULL,
    [Address2] [nvarchar](255) NULL,
    [City] [nvarchar](128) NULL,
    [State] [nvarchar](64) NULL,
    [Zip] [nvarchar](32) NULL,
)
  

Взаимосвязь между этими двумя таблицами:

 ALTER TABLE [dbo].[CollectionSite] WITH CHECK 
    ADD CONSTRAINT [FK_CollectionSite_CollectionSiteAddress_AddressId] 
        FOREIGN KEY([AddressId]) REFERENCES [dbo].[CollectionSiteAddress] ([Id])
GO

ALTER TABLE [dbo].[CollectionSite]  WITH CHECK 
    ADD CONSTRAINT [FK_CollectionSite_CollectionSiteAddress_RemittanceId]  
        FOREIGN KEY([RemittanceId]) REFERENCES [dbo].[CollectionSiteAddress] ([Id])
GO
  

Я хочу выбрать все записи из CollectionSiteAddress , которые не связаны с CollectionSite (ни AddressId ни RemittanceId ). Какой запрос мне следует использовать?

Я пытался:

 SELECT *
FROM CollectionSiteAddress 
LEFT JOIN CollectionSite ON CollectionSiteAddress.Id = CollectionSite.AddressId 
                         OR CollectionSiteAddress.Id = CollectionSite.RemittanceId
  

но он выбирает все записи из CollectionSiteAddress

Ответ №1:

Вам не хватает этого WHERE предложения:

 WHERE CollectionSite.[SiteCode] IS NULL
  

потому что вам нужны все несопоставимые строки CollectionSiteAddress .
Я использовал столбец, [SiteCode] чтобы проверить, так ли это NULL , потому что он не имеет значения null в определении таблицы.
Итак, вы можете написать свой запрос следующим образом (сокращенный с помощью псевдонимов):

 SELECT csa.*
FROM CollectionSiteAddress csa LEFT JOIN CollectionSite cs
ON csa.Id = cs.AddressId OR csa.Id = cs.RemittanceId
WHERE cs.[SiteCode] IS NULL
  

Или используйте NOT EXISTS :

 SELECT csa.*
FROM CollectionSiteAddress csa 
WHERE NOT EXISTS (
  SELECT 1 
  FROM CollectionSite cs
  WHERE csa.Id = cs.AddressId OR csa.Id = cs.RemittanceId
)