首先,对于非描述性标题感到抱歉,我太匆忙了,所以我无法想出更好的标题。
第二:
我的数据库的一部分看起来像下图:
我在系统上有贡献者,每个人都写了很多来源,而且一个来源可以有许多工作贡献者。用户可以根据自己的喜好订阅尽可能多的贡献者,也可以根据需要订阅尽可能多的贡献者。现在,我想要做的只是为特定用户检索所有文章。这些文章要么通过贡献者来源,要么来自用户订阅的来源。为了方便起见,当用户订阅源时,我只需将所有源贡献者复制到users_contributors表。一个棘手的部分,当我检索用户的文章时,我检索了他的贡献者所写的所有文章,以及他所遵循的来源中发布的所有文章,其中这些文章在系统上没有有效的贡献者。 (I.E contributorID为null)。
我创建了以下查询:
Select Articles.ArticleID, Articles.ContributorId, Contributors.Name,
Sources.Name, Articles.ArticleTitle
From Articles
Inner Join Contributors On Articles.ContributorId = Contributors.ContributorId
Inner Join Sources On Articles.SourceId = Sources.SourceID
Where Articles.ContributorId in (
Select ContributorId from Users_Contributors
Where UserID = 3
)
OR (
Articles.SourceId in (
Select SourceId from Users_Sources
Where UserID = 3
)
and
Articles.ContributorId is null
)
上述查询的问题在于,它不会返回任何带有contributorID null的文章。我理解这是因为贡献者表上的连接。在这种情况下我该怎么办?
我需要支持对此查询的分页,将“With {}”子句 适合我,或者我应该 考虑另一种策略?
提前致谢。
Ps:我正在使用SQL Server 2008
答案 0 :(得分:4)
SELECT a.*, s.Name AS SourceName, NULL AS ContributorName
FROM User_Sources us
JOIN Articles a
ON a.SourceID = us.SourceID
JOIN Source s
ON s.SourceID = us.SourceID
WHERE us.UserID = 3
AND a.ContributorID IS NULL
UNION
SELECT a.*, s.Name AS SourceName, c.Name AS ContributorName
FROM User_Contributor uc
JOIN Articles a
ON a.ContributorID = uc.ContributorID
JOIN Contirbutors c
ON c.ContributorID = uc.ContributorID
JOIN Sources s
ON s.SourceID = a.SourceID
WHERE uc.UserID = 3
如果您需要分页,请使用此功能(从80
到100
获取页面):
WITH q AS (
SELECT TOP 100
a.*, s.Name AS SourceName, NULL AS ContributorName
FROM User_Sources us
JOIN Articles a
ON a.SourceID = us.SourceID
JOIN Source s
ON s.SourceID = us.SourceID
WHERE us.UserID = 3
AND a.ContributorID IS NULL
ORDER BY
OrderDate
UNION
SELECT TOP 100
a.*, s.Name AS SourceName, c.Name AS ContributorName
FROM User_Contributor uc
JOIN Articles a
ON a.ContributorID = uc.ContributorID
JOIN Contirbutors c
ON c.ContributorID = uc.ContributorID
JOIN Sources s
ON s.SourceID = a.SourceID
WHERE uc.UserID = 3
ORDER BY
OrderDate
),
page AS
(
SELECT TOP 100 *, ROW_NUMBER() OVER (ORDER BY OrderDate) AS rn
FROM q
)
SELECT *
FROM page
WHERE rn >= 80
答案 1 :(得分:2)
为什么不直接加入
Inner Join Contributors On Articles.ContributorId = Contributors.ContributorID
外部联接?
Left Join Contributors On Articles.ContributorId = Contributors.ContributorID
这将导致它返回所有文章,无论是否存在匹配的SourceID(包括ContributorID为null的情况)。