不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式

Posted

技术标签:

【中文标题】不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式【英文标题】:Only one expression can be specified in the select list when the subquery is not introduced with EXISTS 【发布时间】:2012-11-21 11:10:06 【问题描述】:

这是我的查询

Create FUNCTION [dbo].[CountUses](@couponid INT)
RETURNS INT
AS
   BEGIN
   RETURN
    (
    SELECT  c.Id,
     c.Name,
     c.CreateDate,
     Count(cu.id) NofUses
  FROM   Coupon as  c
     JOIN CouponUse as cu
       ON c.id = cu.couponid
 GROUP  BY c.Id,
     c.Name,
     c.CreateDate
     )
 END 

它给出了错误Only one expression can be specified in the select list when the subquery is not introduced with EXISTS. 问题出在哪里? 除了主要答案之外,我也很感谢您对优化我的查询可能有的任何 cmet...

【问题讨论】:

标量函数只能返回一个值,不能返回四个。看看table-valued function 你的函数试图返回记录集而不是 int。你想得到什么结果? 【参考方案1】:

如果您希望您的函数返回多个值,那么您需要查看Table-Valued Functions。

这些类型的函数返回一个表而不仅仅是一个值。您当前的函数设置为标量函数,因此它只能返回一个值。

如果您想要一个标量值 - 比如说 count,那么您的函数将类似于:

Create FUNCTION [dbo].[CountUses](@couponid INT)
RETURNS INT
AS
   BEGIN
   RETURN
    (
      SELECT Count(cu.id) NofUses  --- this can only return one column
      FROM   Coupon as  c
      JOIN CouponUse as cu
        ON c.id = cu.couponid
      WHERE cu.couponid = @couponid
     )
   END 

如果您打算返回一个数据表,那么您的函数将类似于:

Create FUNCTION [dbo].[CountUses](@couponid INT)
RETURNS @new_table table
(
  id int,
  name varchar(50),
  CreateDate datetime,
  NofUsers int
)
AS
BEGIN
  INSERT INTO @new_table
  SELECT c.Id,
       c.Name,
       c.CreateDate,
       Count(cu.id) NofUses
      FROM   Coupon as  c
      JOIN CouponUse as cu
        ON c.id = cu.couponid
      WHERE cu.couponid = @couponid
      GROUP  BY c.Id,  c.Name,  c.CreateDate

   RETURN
END

【讨论】:

谢谢,@bluefeet 你救了我,最后一件事我怎样才能使NofUses 索引,因为当我尝试这个语句时CREATE INDEX Noofusesindex ON Coupon (NofUses) 它给出了这个错误Column 'NofUses' in table 'Coupon' cannot be used in an index or statistics or as a partition key because it is non-deterministic. @Smartboy 这是一个关于非确定性函数的MSDN article。如果您对创建索引有任何疑问,我会发布另一个问题,因为我不确定是否可行。【参考方案2】:

这将解决问题:

Create FUNCTION [dbo].[CountUses](@couponid INT)
RETURNS TABLE 
AS
RETURN
(
    SELECT  c.Id,
            c.Name,
            c.CreateDate,
            Count(cu.id) NofUses
    FROM   Coupon as  c
    JOIN CouponUse as cu
         ON c.id = cu.couponid
    GROUP  BY c.Id,
              c.Name,
              c.CreateDate
) 

【讨论】:

以上是关于不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式的主要内容,如果未能解决你的问题,请参考以下文章

创建函数时出错 - 如果不使用 EXISTS 引入子查询,则选择列表中只能指定一个表达式

不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式

当不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式。 - SQL 服务器

不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式

SQL - 当不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式

不使用 EXISTS 嵌套 case 语句引入子查询时,选择列表中只能指定一个表达式