Reputation: 23
I need to create a query that returns the top 5 best selling titles. Some titles have multiple authors, creating multiple rows of the same title taking up the spots.
GROUP BY
is not grouping the like titles together and DISTINCT
doesn't work as well.
select top 5
t.sales,
t.title_name,
(a.au_fname + ' ' + a.au_lname) as author,
(t.price * t.sales) as revenue
from titles t
join title_authors ta on ta.title_id = t.title_id
join authors a on a.au_id = ta.au_id
group by
t.title_name,
t.sales,
(a.au_fname + ' ' + a.au_lname),
(t.price * t.sales)
order by t.sales desc
outputs:
When I put DISTINCT
in front of TOP
it still gives me the same output.
I want the titles that are duplicated to be combined, only showing one author.
These are the tables I'm working with: 'titles', 'title_authors', and 'authors'
Thanks to @Venkataraman-R for the solution:
with slight changes to his code I have the exact output I'm looking for
SELECT TOP 5
t.sales,
t.title_name,
string_agg((a.au_fname + ' ' + a.au_lname),';') as 'author(s)',
(t.price * t.sales) as revenue
from titles t
join title_authors ta on ta.title_id = t.title_id
join authors a on a.au_id = ta.au_id
group by t.title_name, t.sales, (t.price * t.sales)
ORDER BY t.sales DESC
Upvotes: 0
Views: 94
Reputation: 12959
I am assuming the SQL Server version as 2016 and writing the below query. I am using STRING_AGG for aggregating the author names for titles.
SELECT TOP 5 t.title_name,string_agg((a.au_fname + ' ' + a.au_lname),';'), max(t.price * t.sales) as revenue
from titles t
join title_authors ta on ta.title_id = t.title_id
join authors a on a.au_id = ta.au_id
group by t.title_name
ORDER BY revenue DESC
Upvotes: 0
Reputation: 926
If you want latest author you can use the following
SELECT TOP 5 t.sales, t.title_name, (a.au_fname + ' ' + a.au_lname) as author, (t.price * t.sales) as revenue
FROM titles t
JOIN (SELECT [title_id],max([au_id]) AS au_id
FROM [test].[dbo].[title_authors] GROUP BY dbo.title_authors.title_id ) as ta on ta.title_id = t.title_id
JOIN authors a on a.au_id = ta.au_id
GROUP BY t.title_name, t.sales, (a.au_fname + ' ' + a.au_lname), (t.price * t.sales)
ORDER BY t.sales DESC
Upvotes: 0
Reputation: 2570
Leave author out of your group by clause, calculating best selling titles does not need data from the authors table.
select top 5 t.sales, t.title_name,
(t.price * t.sales) as revenue
from titles t
group by t.title_name, t.sales,
(t.price * t.sales)
order by t.sales desc
If you need your final result to include a list of authors per title, you can join this result with the authors table later like this:
with combined_title_authors as
(
select title_id, author_name = STRING_AGG(a.au_fname + ' ' + a.au_lname, ', ')
from title_authors ta
inner join authors a on a.au_id = ta.au_id
group by ta.title_id
)
select top 5 t.sales, t.title_name, a.author_name,
(t.price * t.sales) as revenue
from titles t
join combined_title_authors a
on a.title_id = t.title_id
group by t.title_name, t.sales,
(t.price * t.sales), a.author_name
order by t.sales desc
http://sqlfiddle.com/#!18/21f2a/16
Upvotes: 1