【问题标题】:Subquery returned more than 1 value.This is not permitted when the subquery follows =,!=,<,<=,>,>= or when the subquery is used as an expression子查询返回超过 1 个值。当子查询跟在 =,!=,<,<=,>,>= 之后或当子查询用作表达式时,这是不允许的
【发布时间】:2013-04-17 07:17:32
【问题描述】:

我有一个 select * from book table 的存储过程,使用子查询我的查询是

USE [library]
GO

/****** Object:  StoredProcedure [dbo].[report_r_and_l]    Script Date: 04/17/2013 12:42:39 ******/

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER procedure [dbo].[report_r_and_l]
@fdate date,
@tdate date,
@key varchar(1)
as

if(@key='r')

    select * 
    from dbo.books 
    where isbn =(select isbn from dbo.lending where (act between @fdate and @tdate) and (stat ='close'))

else if(@key='l')

    select * 
    from dbo.books 
    where isbn =(select isbn from dbo.lending where lended_date between @fdate and @tdate)

我知道子查询向主查询返回多个查询,但我不知道如何避免此错误,谁能帮助我?

【问题讨论】:

  • 显然select isbn 返回的值不止一个。你可以使用where isbn IN (select isbn ...
  • 使用select top 1 isbn ...select max(isbn) ...。即使你知道只会返回一行,sql-server 也不知道,因为错误信息是基于对命令的静态分析,而不是基于真实数据。

标签: sql-server subquery


【解决方案1】:

问题是这两个查询都返回了不止一行:

select isbn from dbo.lending where (act between @fdate and @tdate) and (stat ='close')
select isbn from dbo.lending where lended_date between @fdate and @tdate

您有两种选择,具体取决于您想要的结果。您可以将上述查询替换为保证返回行的内容(例如,通过使用SELECT TOP 1),或者您可以将= 切换为IN 并返回多行,像这样:

select * from dbo.books where isbn IN (select isbn from dbo.lending where (act between @fdate and @tdate) and (stat ='close'))

【讨论】:

  • 我得到了我的朋友,谢谢。我想知道一件事,只有一个在books表中引用选定的isbn,我想从借出表中选择isbn,从借出表中选择isbn sudent_name从学生表中引用借出表中的索引号,如何检索多个来自多个表的行??
  • 不,原始问题的架构有lended_date。无论您想变得多么迂腐,实际定义的架构每次都胜过良好的语法。
  • 这真是我见过的对IN最简洁易懂的描述了,谢谢!
【解决方案2】:

使用In 而不是=

 select * from dbo.books
 where isbn in (select isbn from dbo.lending 
                where act between @fdate and @tdate
                and stat ='close'
               )

或者你可以使用Exists

SELECT t1.*,t2.*
FROM  books   t1 
WHERE  EXISTS ( SELECT * FROM dbo.lending t2 WHERE t1.isbn = t2.isbn and
                t2.act between @fdate and @tdate and t2.stat ='close' )

【讨论】:

  • SET atRate1 = (SELECT t1.*,t2.* FROM RateCode t1 WHERE EXISTS (SELECT * FROM RateAmount t2 WHERE t1.RateCode = t2.RateCode AND t1.CountryCode = @CCode AND t1.ModuleCode = @MCode)) 我在 t2 上遇到错误。*
【解决方案3】:

您可以使用 IN 运算符,如下所示

select * from dbo.books where isbn IN
(select isbn from dbo.lending where lended_date between @fdate and @tdate)

【讨论】:

    【解决方案4】:
    Using operator 'IN' helps
    
    USE [library]
    GO
    
    /****** Object:  StoredProcedure [dbo].[report_r_and_l]    Script Date: 04/17/2013 12:42:39 ******/
    
    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER procedure [dbo].[report_r_and_l]
    @fdate date,
    @tdate date,
    @key varchar(1)
    as
    
    if(@key='r')
    
        select * 
        from dbo.books 
        where isbn IN (select isbn from dbo.lending where (act between @fdate and @tdate) and (stat ='close'))
    
    else if(@key='l')
    
        select * 
        from dbo.books 
        where isbn IN (select isbn from dbo.lending where lended_date between @fdate and @tdate)
    

    【讨论】:

      猜你喜欢
      • 2014-12-24
      • 2021-11-06
      • 1970-01-01
      • 2016-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-04
      • 2016-08-02
      相关资源
      最近更新 更多