简体   繁体   English

子查询中的SQL子查询

[英]SQL Subqueries within Subqueries

I have a music database with a table Tunes. 我有一个带有表Tunes的音乐数据库。 Each Tunes record contains an ArtistID and Rating . 每个Tunes记录都包含一个ArtistIDRating

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. 我想做的是检索所有唯一的ArtistID字段(很容易)以及一列,该列指示每个Artist曲调的某些Rating值都不为零。

I can make a query to return 0 or 1 to determine if any of an Artists tunes haven't been rated as follows: 我可以进行查询以返回0或1,以确定是否没有对任何Artist乐曲进行以下分级:

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. 上面的查询将返回“ SomeUnrated”真或假(1或0)值。

And.. I can make a query to return all the unique artist IDs that are featured in the Tunes table: 我可以进行查询以返回Tunes表中具有的所有唯一艺术家ID:

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 . 我正在使用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. 如果未分级的null (正确的数据库设计将指示该数值),则可以对分级求和。 A number + null = null . 一个数字+ 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 . 我确实建议将null作为未评级的值,如果您仍然想要零,则可以将null合并为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: 作为进行最终查询的第一步,您可以将DISTINCT替换为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. 结果与DISTINCT相同,但是现在您将能够将其他信息合并到查询中。 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() : 或者,您可以使用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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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