当子查询未引入EXISTS时,只能在选择列表中指定一个表达式。

239

以下是我的查询语句,其中包含一个子查询:

 select count(distinct dNum)
 from myDB.dbo.AQ
 where A_ID in 
  (SELECT DISTINCT TOP (0.1) PERCENT A_ID, 
            COUNT(DISTINCT dNum) AS ud 
 FROM         myDB.dbo.AQ
 WHERE     M > 1 and B = 0 
 GROUP BY A_ID ORDER BY ud DESC)

我收到的错误信息是...

当子查询没有使用 EXISTS 引入时,在 select 列表中只能指定一个表达式。

当我仅运行子查询时,它能返回正确结果,所以我认为主查询可能存在问题?

6个回答

304

在子查询中,您不能返回两个(或多个)列以便在WHERE A_ID IN (subquery)语句中进行比较。因为不知道应该将A_ID与哪一列进行比较。您的子查询必须只返回一个所需列,用于与IN语句的另一侧的列进行比较。因此,查询语句应该是这样的形式:

SELECT * From ThisTable WHERE ThisColumn IN (SELECT ThatColumn FROM ThatTable)
你还想添加排序功能以便只选择前几行,但并不需要将 COUNT 作为一列返回以进行排序;在 ORDER 子句中进行的排序与查询返回的列是独立的。

尝试这样做:
select count(distinct dNum) 
from myDB.dbo.AQ 
where A_ID in
    (SELECT DISTINCT TOP (0.1) PERCENT A_ID
    FROM myDB.dbo.AQ 
    WHERE M > 1 and B = 0
    GROUP BY A_ID 
    ORDER BY COUNT(DISTINCT dNum) DESC)

109

在将返回值分配给变量的where查询中,应该只返回一列和一行。例如:

select * from table1 where Date in (select * from Dates) -- Wrong
select * from table1 where Date in (select Column1,Column2 from Dates) -- Wrong
select * from table1 where Date in (select Column1 from Dates) -- OK

2
它没有帮助我。给了我相同的错误。指定列而不是 * 帮助了我。 - Mohammedsalim Shivani

18

它在抱怨

COUNT(DISTINCT dNum) AS ud 

在子查询中,只能返回一个列,除非您正在执行exists查询。我不确定为什么您要对同一列进行两次计数,表面上看起来与您正在做的重复。这里的子查询仅是一个过滤器,它与连接不同。也就是说,您使用它来限制数据,而不是指定要返回哪些列。


有时候,你可以对查询结果进行联接以解决问题! - JosephDoggie

6
除了这里的很好的回答,如果你想使用现有的子查询,也可以尝试以下方法。
方法: 1)从子查询中选择所需的列(仅限1个)。 2)使用where来映射列名。
代码:
 SELECT count(distinct dNum)
 FROM myDB.dbo.AQ
 WHERE A_ID in 
   (
    SELECT A_ID 
    FROM (SELECT DISTINCT TOP (0.1) PERCENT A_ID, COUNT(DISTINCT dNum) AS ud 
          FROM         myDB.dbo.AQ
          WHERE     M > 1 and B = 0 
          GROUP BY A_ID ORDER BY ud DESC
         ) a 
   )

6

如果有人需要帮助,这是导致我出错的原因: 我需要一个返回JSON的过程,但我忘记添加for json path了:

set @jsonout = (SELECT ID, SumLev, Census_GEOID, AreaName, Worksite 
            from CS_GEO G (nolock) 
                join @allids a on g.ID = a.[value] 
            where g.Worksite = @worksite)

当我尝试保存存储过程时,出现了错误。我通过在存储过程末尾添加for json path代码来解决这个问题。
set @jsonout = (SELECT ID, SumLev, Census_GEOID, AreaName, Worksite 
            from CS_GEO G (nolock) 
                join @allids a on g.ID = a.[value] 
            where g.Worksite = @worksite for json path)

1
谢谢。这也让我意识到,内部查询(用于在较大的JSON对象中生成对象数组)也必须是FOR JSON PATH - JSmart523

1

在子查询中进行投影,您可以使用

SELECT t.col1,t.col2
FROM table1 t 
WHERE EXISTS (SELECT st.col1,st.col2 
               FROM table2 st
               WHERE st.fcol = t.fcol)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接