【问题标题】:SQL AVG in a subquery - results in "Subquery returned more than 1 value.."子查询中的 SQL AVG - 导致“子查询返回超过 1 个值..”
【发布时间】:2014-03-11 13:17:35
【问题描述】:

我发现的搜索结果与我尝试做的有很大不同。我很确定我又想太多了。任何帮助或指示将不胜感激。我正在使用 mssql 和 sql server 2012

我有一个包含 3 列的表 - document_id、member_id 和 rating。我想对表中所有匹配的 document_id 的评分进行平均。

这是整个过程 - 但我将专注于块之后的脏部分:

select      @title = title,
            @description = document.[description],
            @authors = authors,
            @create_date = case when create_date is null then null else convert(varchar(10),create_date, 101) end,
            @revision_date = case when revision_date is null then null else convert(varchar(10),revision_date, 101) end,
            @file_format_id = document.file_format_id,
            @document_category_id = document.document_category_id,
            @size = [size],
            @document_key = document_key,
            @visibility = document.visibility,
            @upload_member_id = upload_member_id,
            @calculated_rating = case when document_category.allow_member_ratings = 1 then (select avg(convert(decimal,rating)) from document_rating where [document].document_id = document_rating.document_id) else null end,
            @member_rating = case when (document_category.allow_member_ratings = 1) then (select convert(decimal,rating) from document_rating where [document].document_id = document_rating.document_id) else null end
from club.dbo.document
    inner join club.dbo.document_category
        on (document.document_category_id = document_category.document_category_id)
        inner join club.dbo.file_format
    on (document.file_format_id = file_format.file_format_id)
where document_id = @document_id
  and document_category.club_id = @club_id

给我错误的部分是@calculated_rating 输出参数的子查询。

@calculated_rating = case when document_category.allow_member_ratings = 1 
then (select avg(convert(decimal,rating)) 
from document_rating 
where [document].document_id = document_rating.document_id) 
else null end,

上面的结果是“子查询返回超过 1 个值。当子查询遵循 =、!=、

所以 - 我尝试了这样的事情:

@calculated_rating = case when document_category.allow_member_ratings = 1 then 
(SELECT AVG(convert(decimal,document_rating.rating)) 
FROM( SELECT SUM(document_rating.rating) rating 
FROM document_rating 
WHERE [document].document_id = document_rating.document_id 
GROUP BY document_rating.document_id) else null end,

那里有一个语法错误,因为我弄得一团糟——但我应该在这里使用别名吗?我正在尝试做的事情是否可能?

已解决

问题不在于平均水平,而在于会员评级。需要在 where 语句中添加额外的限制。

@member_rating = case when (document_category.allow_member_ratings = 1) then (select convert(decimal,rating) from document_rating where @member_id = document_rating.member_id and [document].document_id = document_rating.document_id) else null end

【问题讨论】:

    标签: sql sql-server group-by sql-server-2012 subquery


    【解决方案1】:

    你的问题不是@avg_rating。它是@member_rating。这个子查询是:

            @member_rating = case when (document_category.allow_member_ratings = 1)
                                  then (select convert(decimal,rating)
                                        from document_rating
                                        where [document].document_id = document_rating.document_id
                                       )
                                  else null end
    

    这可能会返回多个值。您可能也希望在此子查询中使用 avg()

    您的@avg_rating 查询很好。这是一个返回一行的聚合查询,因为select 语句中有一个avg(),而没有group by 子句。它将返回一行和一个值,这是子查询应该做的。

    【讨论】:

    • 第二双眼睛有时真的很有帮助。感谢您指出这一点,这是子查询中的错误。我需要在“where”语句中添加一个额外的限制,并向该过程添加一个额外的参数。编辑了我的问题。解决。再次感谢
    【解决方案2】:

    我个人不会使用子查询,因为您有 3 次相同的条件,而是使用左外连接 document_rating on document.document_id = document_rating.document_id 这意味着您可以获得上一个查询的所有行和评分,没有评分的地方只有 null 然后按 document_id 分组(评分)

    这也应该可以提高性能。

    【讨论】:

      猜你喜欢
      • 2013-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-05
      • 2015-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多