【问题标题】:Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >=子查询返回超过 1 个值。当子查询跟随 =、!=、<、<=、>、>= 时,这是不允许的
【发布时间】:2026-01-31 15:20:07
【问题描述】:
'USE [SAPL_BK_NEW]
GO
/****** Object:  StoredProcedure [dbo].[MachineCTE]    Script Date: 11/12/2016 10:32:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--exec MachineCTE 'AQUARELL'

ALTER proc [dbo].[MachineCTE]
(
@companyName varchar(100)
)
AS
BEGIN

CREATE TABLE #MachineCTE
(
ID int,
mcdesp varchar(max),
mccost int, 
mcopsts varchar(30),
State varchar(100),
mcfact varchar(50),
mccomp varchar(60)
);

WITH Machine_CTE(ID,mcdesp,mccost, mcopsts,State,mcfact,mccomp)
AS (SELECT ROW_NUMBER() OVER(ORDER BY mcdesp ASC),
mac.mcdesp  as Machine,count(mac.mccost ) as Cost,count(mcopsts ) as Condition,mcopsts  as [State],mcfact,mccomp
FROM Machine mac    
where Rtrim(mac.mccomp)=@companyName  GROUP BY mcdesp ,mcopsts,mcfact,mccomp)

insert into #MachineCTE select ID,mcdesp,mccost, mcopsts,State,mcfact,mccomp from Machine_CTE




select * from (SELECT 
    CTE.mcdesp as Machines_Name,
    SUM(CTE.mccost) as Total_Machines,
    ISNULL((SELECT mcopsts FROM #MachineCTE MCTE WHERE State='GOOD' and MCTE.mcdesp  = CTE.mcdesp ),0) AS [GOOD],
    ISNULL((SELECT mcopsts  FROM #MachineCTE MCTE WHERE State='IDLE' and MCTE.mcdesp  = CTE.mcdesp ),0) AS [IDLE],
    ISNULL((SELECT mcopsts  FROM #MachineCTE MCTE WHERE State='UR' and MCTE.mcdesp  = CTE.mcdesp ),0) AS [UR] 
FROM #MachineCTE CTE GROUP BY mcdesp) t1 union all
select * from 
(SELECT 
    CTE.mcdesp as Machines_Name,
    '0' as Total_Machines,
    '0' AS [GOOD],
    '0' AS [IDLE],
    '0' AS [UR] 
FROM #MachineCTE CTE where mcfact='EXTRA' GROUP BY mcdesp,mccomp,mcopsts,mcfact)  t2  


drop table #MachineCTE


END'

请帮忙解决这个问题

SELECT 
    CTE.mcdesp as Machines_Name,
    SUM(CTE.mccost) as Total_Machines,
    ISNULL((SELECT mcopsts FROM #MachineCTE MCTE WHERE State='GOOD' and MCTE.mcdesp  = CTE.mcdesp ),0) AS [GOOD],
    ISNULL((SELECT mcopsts  FROM #MachineCTE MCTE WHERE State='IDLE' and MCTE.mcdesp  = CTE.mcdesp ),0) AS [IDLE],
    ISNULL((SELECT mcopsts  FROM #MachineCTE MCTE WHERE State='UR' and MCTE.mcdesp  = CTE.mcdesp ),0) AS [UR] 
FROM #MachineCTE CTE GROUP BY mcdesp

上面的说法是问题

子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的

【问题讨论】:

  • 应该不言自明,其中一个子查询 (SELECT mcopsts FROM #MachineCTE MCTE WHERE State='GOOD' and MCTE.mcdesp = CTE.mcdesp) 返回多个值。最简单的解决方法是使用子查询SELECT TOP 1
  • 扩展 EBrown 已经说过的内容:如果您的 select 子句中有子查询,则该子查询最多可以返回 一个 行。否则你会得到你得到的错误。要么确保子查询(子查询)最多返回一行,要么使用连接重写查询以适应返回的多行。
  • 请阅读 SO 上的 this question 并研究那里发布的答案。您应该能够通过那里发布的答案解决这个问题。
  • 感谢您宝贵的 cmets 解决了问题

标签: c# sql-server-2008 stored-procedures


【解决方案1】:

避免该问题的最简单方法是在子查询中包含TOP 1

ISNULL((SELECT TOP 1 mcopsts FROM #MachineCTE MCTE WHERE State = 'GOOD' and MCTE.mcdesp  = CTE.mcdesp), 0) AS [GOOD],

但是,这只是在回避真正的问题。如果多个可能匹配,为什么您希望只返回一行?如果有多个匹配项,您想如何组合来自多行的值?

【讨论】: