first of all, sorry for the non descriptive title, I'm just too rushed so I couldn't come up with a better one.
Second: I have a portion of my database the looks like the following diagram: 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
)
The problem with the above query is that, it doesn't return any article with contributorID null. I understand this is because of the join on the contributors table. What should I do in such a case?
- Should I consider denormalization?
- What are the prober fields to index on each table for this query to run fast (Rowset returned are approximately 10000)?
I need to support paging on this query, will "With { }" clause be appropriate to me, or should I consider another strategy?
Thanks in advance. Ps: I'm using SQL Server 2008
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
If you need paging, use this (to get the pages from 80
to 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
Why don't you just make this join
Inner Join Contributors On Articles.ContributorId = Contributors.ContributorID
an outer join?
Left Join Contributors On Articles.ContributorId = Contributors.ContributorID
That will cause it to return all Articles, whether or not there is a matching SourceID (includes cases where ContributorID is null).
精彩评论