简体   繁体   中英

SQL Subqueries within Subqueries

I have a music database with a table Tunes. Each Tunes record contains an ArtistID and Rating .

What I want to do is retrieve all of the unique ArtistID fields (easy enough) plus a column indicating that some of the Rating values for each of the Artist's tunes are nonzero.

I can make a query to return 0 or 1 to determine if any of an Artists tunes haven't been rated as follows:

SELECT COUNT() FROM ( 
    SELECT ID FROM Tune WHERE ArtistID=a AND Rating < 1 LIMIT 1 
)

The above query would return a "SomeUnrated" true or false (1 or 0) value.

And.. I can make a query to return all the unique artist IDs that are featured in the Tunes table:

SELECT DISTINCT Artist.ID, Artist.Name
FROM Artist JOIN Tune ON Artist.ID=Tune.ArtistID

How can I combine these two queries so that I a list of values as follows:

Artist.ID  Artist.Name  SomeUnrated

I am using SQLite . Is this an example of a "correlated" subquery?

If your values that are unrated are null (which proper db design would dictate), then you can sum your ratings. A number + null = null . So you would get your false.

Select 
  Artist.ID, 
  sum(rating) as SomeUnrated
from
  Artist 
  join Tune on Artist.ID = Tune.ArtistID
group by
  Artist.ID

Here's a fiddle

I do recommend null as the unrated value, if you still want a zero, you can coalesce the null to 0 .

*I left name off because I forgot it in the schema, simply add it to the select and group by

EDIT:

I believe this is the solution based on comments.

SELECT
  Artist.ID, 
  Artist.Name,
  SUM(Tune.Rating) AS SomeUnrated,
  COUNT()
FROM
  Artist 
  JOIN Tune ON Artist.ID = Tune.ArtistID
GROUP BY
  Artist.ID

As the first step towards the final query, you can replace DISTINCT with a GROUP BY:

SELECT
    Artist.ID,
    Artist.Name
FROM Artist
JOIN Tune ON Artist.ID = Tune.ArtistID
GROUP BY Artist.ID, Artist.Name;

The results would be same as with DISTINCT but now you will be able to incorporate the other piece of information into the query. You will not need that to be a subquery but you will need a conditional to go with it, so...

SELECT
    Artist.ID,
    Artist.Name,
    COUNT(DISTINCT CASE WHEN Rating < 1 THEN 1 END) AS SomeUnrated
FROM Artist
JOIN Tune ON Artist.ID = Tune.ArtistID
GROUP BY Artist.ID, Artist.Name;

Alternatively you could calculate the same result with MAX() :

SELECT
    Artist.ID,
    Artist.Name,
    MAX(CASE WHEN Rating < 1 THEN 1 ELSE 0 END) AS SomeUnrated
FROM Artist
JOIN Tune ON Artist.ID = Tune.ArtistID
GROUP BY Artist.ID, Artist.Name;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM