Reputation: 302
I have one table, Documents, that lists all documents and various information about them. What I'm trying to do is, for a select group of authors, get a count of all documents they've authored in the past year. For each document, we have a column to store the Author name and ID.
I am currently getting what I want with the query below, but my problem is I also need to list all authors that haven't authored any documents. (So, for the Number of Docs Signed column they'd have a zero value) Here's what I have now:
SELECT
[AuthorID] As "Author ID",
RTRIM([AuthorFirstName]) + ' ' + RTRIM([AuthorLastName]) AS "Author",
COUNT(Document.ID) AS "Number of Docs Authored"
FROM Document
WHERE [CompletedStatus] = 'Yes'
AND [AuthorID] IN (<list of author ID's>)
AND [CompletedOn] >= DATEADD(d, -365, getdate())
GROUP BY [AuthorID], [AuthorFirstName], [AuthorLastName]
ORDER BY [Number of Docs Signed] DESC
From reading around on SO I know I think I need some kind of subquery that I can join in order to show a '0' when there are no rows returned by COUNT. But for the life of me I can't figure out how to do it. I'm pretty sure it needs to be something like this.
Upvotes: 2
Views: 3182
Reputation: 1270391
If you have an authors table, you would do:
SELECT a.AuthorID As "Author ID",
RTRIM([a.AuthorFirstName]) + ' ' + RTRIM([a.AuthorLastName]) AS "Author",
COUNT(Document.ID) AS "Number of Docs Authored"
FROM Authors a left outer join
Document d
on a.[AuthorID] = d.[AuthorID] and
d.CompletedStatus = 'Yes' and
[CompletedOn] >= DATEADD(d, -365, getdate())
WHERE a.[AuthorID] IN (<list of author ID's>) and
GROUP BY a.AuthorID, a.AuthorFirstName], a.authorLastName
ORDER BY [Number of Docs Signed] DESC
Note all the conditions on the document are going in the on
clause. Otherwise, the values will be NULL for the Authors with no documents.
If you don't have an authors table, you can create one on the fly:
with authors as (
select <id> as id, <firstname> as authorFirstName, <lastname> as authorLastName union all
select . . .
)
And then use the above query. You need to fill in each author with the name information.
Upvotes: 2
Reputation: 2083
Presumably if they haven't authored any documents, they're not going to have a record in the document table. I guess you have an Authors table or similar?
Something like
SELECT
a.[AuthorID] As "Author ID",
RTRIM(a.[AuthorFirstName]) + ' ' + RTRIM(a.[AuthorLastName]) AS "Author",
COUNT(Document.ID) AS "Number of Docs Authored"
FROM Author a
LEFT OUTER JOIN
Document
ON A.AuthorId = Document.AuthorId
AND [CompletedStatus] = 'Yes'
AND [CompletedOn] >= DATEADD(d, -365, getdate())
WHERE A.[AuthorID] IN (<list of author ID's>)
GROUP BY a.[AuthorID], a.[AuthorFirstName], a.[AuthorLastName]
Upvotes: 2
Reputation: 26940
Start from the Authors table and do a left outer join to the documents table. This means you need to move the criteria into the outer join...
SELECT
[AuthorID] As "Author ID",
RTRIM([AuthorFirstName]) + ' ' + RTRIM([AuthorLastName]) AS "Author",
COUNT(Document.ID) AS "Number of Docs Authored"
FROM
Author a
LEFT OUTER JOIN Document d on d.AuthorID = a.ID
AND [CompletedStatus] = 'Yes'
AND [CompletedOn] >= DATEADD(d, -365, getdate())
WHERE
a.ID IN (<list of author ID's>)
GROUP BY a.[ID], [AuthorFirstName], [AuthorLastName]
ORDER BY [Number of Docs Signed] DESC
Upvotes: 3