0

我的 Microsoft SQL Server 2008 数据库中有两个查找/引用表(已订阅和未订阅),其结构如下:

UserId int
PublicationId int

这些字段作为复合索引一起索引。

我想要做的是找到未订阅表中存在的所有记录,这些记录在已订阅表中没有匹配记录(匹配 UserId 和 PublicationId)

在功能上,我想要类似的东西:

select PublicationId, UserId
from Unsubscribed
where PublicationId, UserId not in (
   select PublicationId, UserId
   from Subscribed
)

谁能指出我正确的方向?

谢谢。

4

4 回答 4

3
SELECT PublicationId, UserId
FROM   Unsubscribed
MINUS
SELECT PublicationId, UserId
FROM   Subscribed
于 2012-02-16T12:50:31.317 回答
2

您可以使用 aleft join来查找不匹配的出版物和用户。

SELECT U.[PublicationId], U.[UserId]
FROM [Unsubscribed] AS U
    LEFT JOIN [Subscribed] AS S ON S.[PublicationId] = U.[PublicationId]
        AND S.[UserId] = U.[UserId]
WHERE S.[PublicationId] IS NULL
    AND S.[UserId] IS NULL

或者,如果您使用的是 Microsoft SQL Server 2005 / 2008,那么您可以使用Except关键字(使用Intersect相反的关键字)。

SELECT [PublicationId], [UserId]
FROM [Unsubscribed] 

EXCEPT

SELECT [PublicationId], [UserId]
FROM [Subscribed]
于 2012-02-16T12:49:45.250 回答
2

您可以随时转换INEXISTS. 在你的情况下,这看起来像这样:

select PublicationId, UserId
from Unsubscribed
where
   not exists (
      select *
      from Subscribed
      where Subscribed.PublicationId = Unsubscribed.PublicationId
         and Subscribed.UserId = Unsubscribed.UserId
   )

顺便说一句,如果您使用的是 Oracle,您实际上可以直接实现您的初衷(只需添加几个括号):

select PublicationId, UserId
from Unsubscribed
where (PublicationId, UserId) not in (
   select PublicationId, UserId
   from Subscribed
)
于 2012-02-16T12:57:18.160 回答
1

您可以使用LEFT JOIN来实现这一点;

SELECT U.*, S.PublicationId
FROM Unsubscribed U
LEFT JOIN Subscribed S ON U.PublicationId = S.PublicationId AND U.UserId = S.UserId
WHERE S.PublicationId IS NULL

如果您是新加入的,Jeff Atwood 的视觉解释是一个很好的起点。

实际上,查询所做的是带回 ubsubscribed 中所有在 Subscribed 中具有匹配行的行,以及 Unsubscribed 中所有在 subscribed 中没有匹配行的行 - subscribed 中的行用 NULL 表示这些。

于 2012-02-16T12:50:28.323 回答