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

Posted

技术标签:

【中文标题】当不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式。 - SQL 服务器【英文标题】:Only one expression can be specified in the select list when the subquery is not introduced with EXISTS. - SQL Server 【发布时间】:2018-09-12 21:01:07 【问题描述】:

我正在尝试创建一个存储过程,并且我使用 SQL Server 编写了这段代码,但我得到了错误

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

我不知道怎么解决。

CREATE PROCEDURE Calculus
AS
BEGIN
    SELECT
        -- **** Media (Average) **** --
        (SELECT CAST(AVG(CAST(CC AS NUMERIC)) AS VARCHAR(MAX))
         FROM CHALLENGE AS Media),
        -- **** Mediana **** --
        (SELECT CASE WHEN COUNT(CC) % 2 = 0 
                THEN (SELECT TOP 1 ((SELECT TOP 1 CC 
                                     FROM (SELECT TOP 50 PERCENT CC FROM CHALLENGE ORDER  BY CC ASC) AS X
                                     ORDER  BY CC DESC)
                                  + (SELECT TOP 1 CC
                                     FROM (SELECT TOP 50 PERCENT CC FROM CHALLENGE ORDER  BY CC DESC) AS Y
                                     ORDER  BY CC ASC)) / 2)
                ELSE (SELECT TOP 1 CC
                      FROM (SELECT TOP 50 PERCENT CC FROM CHALLENGE ORDER  BY CC) AS X
                      ORDER  BY CC DESC)
                END AS Mediana
         FROM   CHALLENGE),
        -- **** Moda **** --
        (SELECT TOP 1 CC, COUNT(CC) AS Veces
         FROM CHALLENGE
         GROUP BY CC
         ORDER BY COUNT(CC)) AS Moda,
        -- **** Min **** --
        MIN(CC) AS Minimo,
        -- **** Max **** --
        MAX(CC) AS Maximo
    FROM
        CHALLENGE
END

【问题讨论】:

您好,欢迎来到 SO。我会说这不是“可修复的”。里面几乎没有什么可以挽救的。它需要重新启动。我计算了至少 9-10 个选择语句,它们都击中了完全相同的表。存在多个逻辑和句法错误。 Here 是一个很好的起点。 但是如果你不想让它变得更好而只是让它工作看看你的 Moda 子查询,里面有两列。你找不到它是一个很好的迹象,它需要一些重要的帮助。 @JuanPenaranda 。 . .您不理解错误消息的哪一部分?看起来很清楚。 【参考方案1】:

为了清楚起见,您应该首先重构您的存储过程。

以下示例供参考

CREATE PROCEDURE Calculus
AS
  BEGIN
      DECLARE @Media varchar(max)
      DECLARE @Mediana varchar(max)
      DECLARE @topbottom numeric
      DECLARE @bottomtop numeric
      DECLARE @Moda varchar(max)
      SELECT 
            @Media= Cast(Avg(Cast (CC AS numeric)) AS varchar(max))
      FROM CHALLENGE

      SELECT 
        TOP 50 PERCENT CC 
      INTO #TOP
      FROM   CHALLENGE
      ORDER  BY CC ASC

      SELECT 
        TOP 50 PERCENT CC 
      INTO #BOTTOM
      FROM   CHALLENGE
      ORDER  BY CC DESC

      SELECT 
            TOP 1 @topbottom=CAST(CC as numeric)
      FROM   #TOP X
      ORDER  BY CC DESC 

      SELECT 
        TOP 1 @bottomtop=CAST(CC as numeric)
       FROM   #BOTTOM Y
       ORDER  BY CC ASC

      SELECT @Mediana=
            CASE
                WHEN Count(CC) % 2 = 0 THEN (@bottomtop+@topbottom)/2
                ELSE @topbottom
              END 
       FROM   CHALLENGE

      SELECT TOP 1 
        @Moda= CC
        FROM
      (
      SELECT CC,Count(CC) AS Veces
       FROM   CHALLENGE
       GROUP  BY CC
       )
       ORDER  BY Veces


      SELECT
        Media=@Media,
        Mediana=@Mediana,
        Moda= @Moda,
        Minimo=Min(CC),
        Maximo=Max(CC)
      FROM   CHALLENGE

      drop table #top
      drop table #bottom
  END 

【讨论】:

【参考方案2】:

您应该更改您的查询并将每个子查询放入 (OUTER APPLY) 连接中

像这样:

   CREATE PROCEDURE Calculus
    AS
    BEGIN
        SELECT
              MediaTableName.MediaFieldName

        FROM
            CHALLENGE
        OUTER APPLY 
            (SELECT CAST(AVG(CAST(CC AS NUMERIC)) AS VARCHAR(MAX)) as MediaFieldName
             FROM CHALLENGE AS t1
             WHERE t1.IDentity = CHALLENGE.IDentity /* this line create join condition and its up to you how use it*/
             ) as MediaTableName

    END

对于每个子查询,使用一个外部应用连接 你可以删除where子句行

【讨论】:

【参考方案3】:

这部分查询导致错误。

这是一个子查询,您正试图从中返回 2 列(这会导致错误)。

TOP 1 CCCOUNT(CC)

(选择前 1 个抄送 ,COUNT(CC) AS 向量 来自挑战 按 CC 分组 按数量排序(CC))作为模式

不知道该建议什么,因为您肯定是唯一知道您打算从这里得到什么的人。

【讨论】:

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

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

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

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

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

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

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