Let’s say I have two tables with these data:
author
id | name
---------
1 | John
2 | Jack
3 | James
4 | Bob
5 | Gorge
book
id | author_id | title | state
-------------------------------------
1 | 1 | book_1 | published
2 | 1 | book_2 | pre-published
3 | 1 | book_3 | published
4 | 1 | book_4 | rejected
5 | 2 | book_5 | published
6 | 3 | book_6 | rejected
7 | 3 | book_7 | pre-published
8 | 4 | book_8 | rejected
What I want is a sql query that gives me each of author’s id and name and number of published book even if they have 0 published. I think it might be an easy query but I stuck in it, what I want is:
id | name | num_of_published_books
------------------------------------
1 | John | 2
2 | Jack | 1
3 | James | 0
4 | Bob | 0
5 | Gorge | 0
I’m able to fetch first two rows John
and Jack
. and also I am able to group them based on author_id
and state
. but it was not what I want.
note that I don’t want to use subquery.
4
Answers
Hope it will help you.
b.state = 'published'
, we can delete the published books, the result isfalse(0)
ortrue(1)
.OR NULL
is to deal withNULL
. In my memory, when usingOR
operator to compare non-null value andNULL
value, the result will always beNULL
.COUNT
willNULL
is ignored.true(1) OR NULL
andfalse(0) OR NULL
, and their results aretrue(1)
andfalse(0)
respectively.Count
counts the number that is notNULL
.To achieve the desired result, you can use a LEFT JOIN and GROUP BY in your SQL query.
The LEFT JOIN ensures that all authors from the "author" table are included, even if they have no corresponding records in the "book" table.
Here’s the SQL query that should give you the expected result:
Check query result http://sqlfiddle.com/#!9/0db9c8a/1/0
Explanation:
The query uses a LEFT JOIN to combine the "author" and "book" tables based on the "author_id." It then employs the SUM function with a CASE statement to count the number of published books for each author (1 for ‘published’, 0 for others). COALESCE is used to handle NULL values and replace them with 0 in case an author has no published books.
One more version using aggregation with FILTER.
Please note that
min(a.name)
may become simplya.name
ifauthor.id
is primary key.DB Fiddle