Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Databases Querying Relational Databases Subqueries Review and Practice

Review and Practice - Subqueries

Not entirely sure what they're asking me to do on the first practice question: -

"Generate a report that lists the book titles from both locations and count the total number of books with the same title."

I don't see how to a LEFT OUTER JOIN or an INNER JOIN to get all of the titles into one column (if that's indeed what the question wants) nor what to do with a SUBSELECT to get the same. Help would be appreciated.

Edit: I can fake an answer with a UNION, but that seems out of scope.

9 Answers

Boban Talevski
Boban Talevski
24,793 Points

I would assume that the task was asking for what all the above answers are getting as a result. But, if you reread it carefully, it's asking for a report listing all book titles from both locations AND the total number of books with the same title. So, it can also mean list all the titles as well as the number of books with the same title, all in the same query.

In any case, I attempted to do it and managed to make it work, though it doesn't look really readable. Both the query and to some extent the result :). Also, note there are two ways of adding this information for the number of books with the same title to the result.

It can be done as an additional row in the result set.

This is the query:

SELECT title, COUNT(*) AS Number FROM (
  SELECT title FROM books_north
  UNION ALL
  SELECT title FROM books_south
  ) GROUP BY title
UNION
SELECT "Total number of books with the same title", COUNT(*)
FROM (SELECT title, COUNT(*) AS numBooks FROM (
  SELECT title FROM books_north
  UNION ALL
  SELECT title FROM books_south
  ) GROUP BY title) AS t
WHERE t.numBooks >= 2

This will display the list of book titles and the bottom row will the display the number of books with the same title. It works by just adding a single row to the resultset using UNION and the first column is hardcoded to show "Total number of books with the same title" and the second column displays the number of the books with the same title, which for this example is 12.

Now, there's also another option and that is to add an additional column to the result set to present the number of books with the same title, and this is the query:

SELECT * FROM 
    (SELECT title, COUNT(*) AS Number FROM (
      SELECT title FROM books_north
      UNION ALL
      SELECT title FROM books_south
      ) GROUP BY title
    )
LEFT OUTER JOIN
    (SELECT * FROM
    (SELECT COUNT(*) AS "Total number of books with the same title"
    FROM (SELECT title, COUNT(*) AS numBooks FROM (
      SELECT title FROM books_north
      UNION ALL
      SELECT title FROM books_south
      ) GROUP BY title) AS t
    WHERE t.numBooks >= 2))

So we have a third column here labeled "Total number of books with the same title" added using a LEFT OUTER JOIN (cause other's weren't supported by SQLite, right?) without a join condition, so it's just added, no questions asked as far as I can tell. The downside of this approach is that it shows the number in every row. But it could be considered more readable since we don't have to scroll down to the bottom to get the required information about the number of books with the same title.

There probably is a way to avoid showing 1 and 2 for each of the book titles and make it all cleaner, like removing the second column altogether in the second approach by using an additional query on top of the one above which selects only the first and third column, but I'll stop here :).

Tatiana Vasilevskaya
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Tatiana Vasilevskaya
Python Web Development Techdegree Graduate 28,600 Points

Here is a variant using a subquery

SELECT title, COUNT(*) AS num FROM (SELECT title FROM books_north UNION ALL SELECT title FROM books_south) GROUP BY title;

Could you explain why this works?

Freddie Kuhle
Freddie Kuhle
8,037 Points

I found the below was a pretty readable way to get the answer:

SELECT title, COUNT(title) FROM ( SELECT title FROM books_north UNION ALL SELECT title FROM books_south) GROUP BY title;

I used the following query and I think it does the job:

SELECT COUNT(*) , title FROM ( SELECT title FROM books_north UNION ALL SELECT title FROM books_south) GROUP BY 2;

This was my solution

SELECT b.title, COUNT(b.title) AS Amount FROM (SELECT title FROM books_north UNION ALL SELECT title FROM books_south ORDER BY title) As b GROUP BY title;
Ololo Olololo
PLUS
Ololo Olololo
Courses Plus Student 1,816 Points

I think that Tatiana Vasilevskaya's answer is not correct, because the task is to "count the total number of books with the same title", so I suggest the following solution:

SELECT COUNT(*) 
FROM (
  SELECT title FROM books_north
  INTERSECT
  SELECT title FROM books_south
) AS duplicates
Petar Pavlov
Petar Pavlov
16,184 Points

:D same result with: SELECT COUNT(*) FROM books_north INNER JOIN (SELECT * FROM books_south) AS t ON books_north.title = t.title;

Remi Vledder
Remi Vledder
14,144 Points

It depends on what part of the question you interpret.

"-- Generate a report that lists the book titles from both locations and count the total number of books with the same title."

The end part "...count the total number of books with the same title." would indeed indicate to count the total of duplicate books. But the first part of the sentence "...list the book titles..." indicate that the end result should be a table with books.

Abdullah Jassim
Abdullah Jassim
4,551 Points

Can someone please advise whats wrong with this answer and why am I getting only one column?

`` SELECT books_north.title, COUNT(books_north.id) AS BN_Count FROM books_north UNION ALL SELECT books_south.title, COUNT(books_south.id) AS BS_Count FROM books_south GROUP BY title;

Craig Willcox
PLUS
Craig Willcox
Courses Plus Student 6,290 Points

-- Generate a report that lists the book titles from both locations and count the total number of books with the same title.

select title from ( select title from ( SELECT TITLE FROM BOOKS_NORTH UNION all SELECT TITLE FROM BOOKS_SOUTH ) group by title ) union all

select  '****** Total number of duplcate titles ****** ' || count(*) title from 
    (
        SELECT TITLE FROM BOOKS_NORTH
        intersect
        SELECT TITLE FROM BOOKS_SOUTH        
    )

title A Brief History of Time Armada Congo Emma Frankenstein Harry Potter and the Chamber of Secrets Harry Potter and the Deathly Hallows Harry Potter and the Goblet of Fire Harry Potter and the Half-Blood Prince Harry Potter and the Order of the Phoenix Harry Potter and the Philosopher's Stone Harry Potter and the Prisoner of Azkaban Jurassic Park Pride and Prejudice Ready Player One Sphere The Martian The Universe in a Nutshell ****** Total number of duplcate titles ****** 12

Craig Willcox
PLUS
Craig Willcox
Courses Plus Student 6,290 Points

-- Generate a report that lists the book titles from both locations and count the total number of books with the same title.

select title from ( select title from ( SELECT TITLE FROM BOOKS_NORTH UNION all SELECT TITLE FROM BOOKS_SOUTH ) group by title ) union all

select  '****** Total number of duplcate titles ****** ' || count(*) title from 
    (
        SELECT TITLE FROM BOOKS_NORTH
        intersect
        SELECT TITLE FROM BOOKS_SOUTH        
    )