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

时间:2013-04-17 07:17:32

标签: sql-server subquery

我有一个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)

我知道子查询是对主查询返回多个查询,但我不知道如何避免这个错误,任何人都可以帮助我吗?

4 个答案:

答案 0 :(得分:24)

问题是这两个查询都返回多行:

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),或者您可以将=切换为{{1并返回多行,如下所示:

IN

答案 1 :(得分:9)

使用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' )

答案 2 :(得分:4)

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

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

答案 3 :(得分:0)

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)