子查询返回的值超过1。子查询遵循=,!=,<,< =,>,> =时不允许这样做

时间:2011-08-03 15:21:39

标签: sql sql-server sql-server-2005

我遇到了路障。我试图使用由select中的5个子查询组成的查询从数据库中检索求和数据。我需要为每列返回多行,这就是我所拥有的。

  select distinct ISNULL((select sum(i.Amount) from invoice i inner join vSchool v on  v.SchoolID = i.SchoolID and v.SystemID = '617'
    inner join request R on R.requestid = i.requestid
    where i.SchoolID =       v.SchoolID                                       
    and i.ReimbursementTypeID = '28'            
    and month(R.FundMonth)='2'
    and R.requesttypeID = '32'                                         
    group by v.SchoolID),0) as FVTotal
   ,ISNULL((select sum(i.Amount) from invoice i inner join vSchool v on v.SchoolID =   i.SchoolID and v.SystemID = '617'
   inner join request R on R.requestid = i.requestid
   inner join grantsystem G on G.grantsystemID = R.grantsystemID
   inner join grants GR on GR.grantsid = G.grantsID
   where i.SchoolID = v.SchoolID                                          
   and i.ReimbursementTypeID = '29'         
  and month(R.FundMonth)='2'
  and R.requesttypeID = '32'                                       
  and GR.grantsid = '5' or GR.grantsid = '7'
  group by v.schoolid),0)  as OpLaborTotal
  ,ISNULL((select sum(i.Amount) from invoice i inner join vSchool v on v.SchoolID =   i.SchoolID and v.SystemID = '617'
  inner join request R on R.requestid = i.requestid
  where i.SchoolID =   v.SchoolID                                         
 and i.ReimbursementTypeID = '31'           
 and month(R.FundMonth)='2'
 and R.requesttypeID = '32'                                        
 group by v.schoolid),0)  as SupplyTotal
 ,ISNULL((select sum(i.Amount) from invoice i inner join vSchool v on v.SchoolID =   i.SchoolID and v.SystemID = '617'
 inner join request R on R.requestid = i.requestid
 where i.SchoolID = v.SchoolID                                        
 and i.ReimbursementTypeID = '30'           
 and month(R.FundMonth)='2'
 and R.requesttypeID = '32'                                        
 group by v.schoolid),0) as LargeTotal
,ISNULL((select sum(i.Amount) from invoice i inner join vSchool v on v.SchoolID =   i.SchoolID and v.SystemID = '617'
inner join request R on R.requestid = i.requestid
inner join grantsystem G on G.grantsystemID = R.grantsystemID
inner join grants GR on GR.grantsid = G.grantsID
where i.SchoolID = v.SchoolID                                         
and i.ReimbursementTypeID = '29'            
and month(R.FundMonth)='2'
and R.requesttypeID = '32'                                         
and GR.grantsid = '6' or GR.grantsid = '8'
group by v.schoolid),0) as AdminLabor

此查询为我提供了有关返回多个值的错误。是否有一种解决方法可以让我做我想在这里做的事情?

6 个答案:

答案 0 :(得分:4)

您的查询可能完整的重构,以避免子查询导致的大量头痛和重复......

SELECT
  v.schoolid
  ISNULL(SUM(CASE WHEN i.ReimbursementTypeID = '28'                              THEN i.Amount END),0)  as FVTotal,
  ISNULL(SUM(CASE WHEN i.ReimbursementTypeID = '29' AND GR.grantsid IN ('5','7') THEN i.Amount END),0)  as OpLaborTotal,
  ISNULL(SUM(CASE WHEN i.ReimbursementTypeID = '31'                              THEN i.Amount END),0)  as SupplyTotal,
  ISNULL(SUM(CASE WHEN i.ReimbursementTypeID = '30'                              THEN i.Amount END),0)  as LargeTotal,
  ISNULL(SUM(CASE WHEN i.ReimbursementTypeID = '29' AND GR.grantsid IN ('6','8') THEN i.Amount END),0)  as AdminLabor
FROM
  invoice i
INNER JOIN
  vSchool v
    ON  v.SchoolID = i.SchoolID
    AND v.SystemID = '617'
INNER JOIN
  request R
    ON R.requestid = i.requestid
LEFT JOIN
  grantsystem G
    ON G.grantsystemID = R.grantsystemID
LEFT JOIN
  grants GR
    ON GR.grantsid = G.grantsID
WHERE
  MONTH(R.FundMonth)  = '2'    
  AND R.requesttypeID = '32'
GROUP BY
  v.SchoolID  

注意:您已将所有ID包含在引号中。 ID 真的是字符串吗?如果它们是数字,请不要使用引号:)

答案 1 :(得分:1)

查询对我来说太大了,我想要重新格式化它并计算出所有连接。但是你可能会有一个快速而肮脏的修复方法......

选择 FROM vSchool表,然后通过引用vSchool的外部实例将子查询转换为相关子查询...

select  main.schoolid,
        ,ISNULL((select sum(i.Amount) from invoice i inner join vSchool v on v.SchoolID = i.SchoolID and v.SystemID = '617'
                                          inner join request R on R.requestid = i.requestid
                                          where i.SchoolID = v.SchoolID                                       
                                          and i.ReimbursementTypeID = '28'          
                                          and month(R.FundMonth)='2'
                                          and R.requesttypeID = '32'                                       
                                          AND v.schoolid = main.schoolid),0) as FVTotal
        ,ISNULL((select sum(i.Amount) from invoice i inner join vSchool v on v.SchoolID = i.SchoolID and v.SystemID = '617'
                                          inner join request R on R.requestid = i.requestid
                                          inner join grantsystem G on G.grantsystemID = R.grantsystemID
                                          inner join grants GR on GR.grantsid = G.grantsID
                                          where i.SchoolID = v.SchoolID                                       
                                          and i.ReimbursementTypeID = '29'          
                                          and month(R.FundMonth)='2'
                                          and R.requesttypeID = '32'                                       
                                          and (GR.grantsid = '5' or GR.grantsid = '7')
                                          AND v.schoolid = main.schoolid),0)  as OpLaborTotal
        ,ISNULL((select sum(i.Amount) from invoice i inner join vSchool v on v.SchoolID = i.SchoolID and v.SystemID = '617'
                                          inner join request R on R.requestid = i.requestid
                                          where i.SchoolID = v.SchoolID                                       
                                          and i.ReimbursementTypeID = '31'          
                                          and month(R.FundMonth)='2'
                                          and R.requesttypeID = '32'                                       
                                          AND v.schoolid = main.schoolid),0)  as SupplyTotal
        ,ISNULL((select sum(i.Amount) from invoice i inner join vSchool v on v.SchoolID = i.SchoolID and v.SystemID = '617'
                                          inner join request R on R.requestid = i.requestid
                                          where i.SchoolID = v.SchoolID                                       
                                          and i.ReimbursementTypeID = '30'          
                                          and month(R.FundMonth)='2'
                                          and R.requesttypeID = '32'                                       
                                          AND v.schoolid = main.schoolid),0) as LargeTotal
        ,ISNULL((select sum(i.Amount) from invoice i inner join vSchool v on v.SchoolID = i.SchoolID and v.SystemID = '617'
                                          inner join request R on R.requestid = i.requestid
                                          inner join grantsystem G on G.grantsystemID = R.grantsystemID
                                          inner join grants GR on GR.grantsid = G.grantsID
                                          where i.SchoolID = v.SchoolID                                       
                                          and i.ReimbursementTypeID = '29'          
                                          and month(R.FundMonth)='2'
                                          and R.requesttypeID = '32'                                       
                                          and (GR.grantsid = '6' or GR.grantsid = '8')
                                          AND v.schoolid = main.schoolid),0) as AdminLabor
FROM
  vSchool AS [main]

我几乎肯定你可以将这个查询重构成一些不那么繁琐的东西,但正如我所说,那里有太多让我想解开它,对不起。

答案 2 :(得分:0)

是的,您可以通过让每个子选择SELECT TOP 1来运行查询。

请记住,您丢失了显然想要在此处选择的数据,因此这可能不是理想的解决方案!

答案 3 :(得分:0)

解决方案,如果您不需要每个学校的总计

我在这里做了一个有根据的猜测,并说你应该删除子查询中的所有group by子句,因为你似乎并不真正关心每个学校的总计 。你似乎想要总和。所以你不需要group by。然后,您将只有一个记录在每个子查询中包含一个总和。

如果您确实需要每个学校的总计

如果你确实需要分组(例如,如果你需要每个学校的总计 ),那么也许你应该将你的查询改为:

select 'fvtotal' as type,
       sum(amount) as total,
       schoolid as schoolid
from ... -- first filtered table source here
group by schoolid

union

select 'oplabortotal' as type,
       sum(amount) as total,
       schoolid as schoolid
from ... -- second filtered table source here
group by schoolid

union

-- etc

这将产生一个这种形式的表

+------------+-----------+---------+
|type        | total     | schoolid|
+------------+-----------+---------+
|fvtotal     |1234       |1        |
|fvtotal     |32985      |2        |
|oplabortotal|341        |1        |
|...         |           |         |
+------------+-----------+---------+

答案 4 :(得分:0)

没有冒犯,但这个问题......好不好意思。当我正在阅读时,它实际上没有 抓取页面并咬人,所以我会咬我的舌头。

你使用ISNULL()似乎很奇怪。

试试这个。而不是这种格式:

ISNULL(
    (select sum(i.Amount) 
     from invoice i 
     inner join vSchool v 
     on  v.SchoolID = i.SchoolID 
     and v.SystemID = '617'
     inner join request R 
     on R.requestid = i.requestid
     where i.SchoolID = v.SchoolID                                       
     and i.ReimbursementTypeID = '28'            
     and month(R.FundMonth)='2'
     and R.requesttypeID = '32'                                         
     group by v.SchoolID),0) as FVTotal

试试这个

(select sum(isnull(i.Amount,0)) 
     from invoice i 
     inner join vSchool v 
     on  v.SchoolID = i.SchoolID 
     and v.SystemID = '617'
     inner join request R 
     on R.requestid = i.requestid
     where i.SchoolID = v.SchoolID                                       
     and i.ReimbursementTypeID = '28'            
     and month(R.FundMonth)='2'
     and R.requesttypeID = '32'                                         
     group by v.SchoolID) as FVTotal

为每个子查询执行此操作...

PS - 这个查询的编写非常糟糕。你应该认真考虑改革。

答案 5 :(得分:0)

我会做更像

的事情
select 
    i.ReimbursementTypeID, GR.grantsid, v.SchoolID, sum(i.Amount) as Total 
from 
    invoice i inner join vSchool v on  v.SchoolID = i.SchoolID  inner join request R on R.requestid = i.requestid
    left outer join grantsystem G on G.grantsystemID = R.grantsystemID left outer join grants GR on GR.grantsid = G.grantsID
where   
    v.SystemID = '617'                                    
    and ((i.ReimbursementTypeID in('28','30','31')) or  (i.ReimbursementTypeID = '29' and GR.grantsid in('5', '6', '7','8')))
    and month(R.FundMonth)='2'
    and R.requesttypeID = '32'                                         
group by 
    i.ReimbursementTypeID, GR.grantsid, v.SchoolID

您只需要您的联接和标准一次,而不是每个reimbursementTypeID / grantsID一次,您可以按这些字段值进行分组以创建并行总和。