子查询返回了1个以上的值错误sql

时间:2019-03-27 15:29:10

标签: sql tsql join

我正在尝试使用子查询进行查询,在此我希望对标识号求和。但这给了我错误: '子查询返回的值超过1。当子查询遵循=,!=,<,<=,>,> =或将子查询用作表达式时,不允许这样做。'

我已经尝试过:

CREATE VIEW [dbo].[VW_Verblijfsobjecten_uitgeklapt]
AS
SELECT a.[Gemeentecode-AOB]
,a.[Code objecttypering-AOB]
,a.[Identificatie-AOB]
,a.[Gebruiksdoel]
,a.[Datum ontstaan-AOB]
,a.[Status code-AOB]
,a.[Buurtnaam]
,a.[Huisnummer]
,a.[Huisnummertoevoeging]
,a.[Postcode]
,a.[Identificatie-PND]
,a.[Geometrie]
,a.[Datum einde gebruik-AOB]
,a.[Einddatum-AOB]
,c.[DateValue]
,a.[Woonplaatsnaam]
,(SELECT COUNT(DISTINCT(b.[Identificatie-AOB]))
  FROM [Clean.VBO] as b
  WHERE b.[Datum ontstaan-AOB] <= c.[DateValue] 
  AND (b.[Gebruiksdoel] IN ('1', '111', '11141', '11161', '121', '131', '141', '151', '161', '181'))
  AND (b.[Status code-AOB] <> 82)  
  AND (b.[Datum einde gebruik-AOB] = '2999-01-01' OR b.[Datum einde gebruik-AOB] > c.[DateValue])
  GROUP BY b.[Woonplaatsnaam]) AS AantalWoningenInDeTijd
FROM [Clean.VBO] as a 
INNER JOIN [Clean.Peilkalender] as c
ON a.[Datum ontstaan-AOB] <= c.[DateValue]

我希望它是根据“ woonplaatsnaam”而不是总数来计算识别码的。

5 个答案:

答案 0 :(得分:3)

您的子查询按b分组。[Woon ...没人知道的长的难以置信的语言名称]

这将导致(可能)多个结果,具体取决于您要分组的列。这在子查询的SELECT或sql语句部分中是不允许的。

要获取所需结果,您可以做的是将子查询放在查询的from部分中。为它分配一个手柄,并根据您认为合适的条件进行适当的联接。然后,可以在查询的所选部分中使用所得的合并值。

SELECT a.x, b.y, c.z 
   FROM A a 
   INNER JOIN B b
   INNER JOIN (<subselect>) c 
                              ON a.a = c.a
   WHERE ...

答案 1 :(得分:2)

该错误消息非常具有描述性:

  

子查询返回了多个值。当   子查询遵循=,!=,<,<=,>,> =,或当子查询用作   表达式。

让我们假设您要使用一个期望单个值的比较运算符。示例:

yourcolumn > (select yourcolumn2 from yourtable where yourcondition)

现在,让我们假设您的子查询将返回两个值:5和7。让我们进一步假设,在您的列为6的情况下。因此,这意味着您有兴趣知道6>(5,7)。但是,该比较应该如何执行? 6> 5为真,但6> 7为假。那么结果应该是什么呢?真正?假?空值?难以确定。没有明确定义的方法可以评估该表达。因此,对于这些运算符,您的子查询将需要一个结果。在某些情况下,不需要唯一的结果。示例:

yourcolumn in (select yourcolumn2 from yourtable where yourcondition)

在这种情况下,您会对值是否在集合内感兴趣。

您的实际查询正在尝试插入表中。字段的值由子查询确定,但是如果子查询具有多个结果,则子查询的结果是矛盾的,因此无法确定该字段的值,即显示停止符。

因此,根据您的需要,您将需要应对这种情况。您可以将分组查询用作表并将其加入。或者您可以避免分组。或者,您可以确保将所有记录都通过一个位置插入一个组。

答案 2 :(得分:1)

从缩放器子查询中删除分组依据

CREATE VIEW [dbo].[VW_Verblijfsobjecten_uitgeklapt]
AS
SELECT a.[Gemeentecode-AOB]
,a.[Code objecttypering-AOB]
,a.[Identificatie-AOB]
,a.[Gebruiksdoel]
,a.[Datum ontstaan-AOB]
,a.[Status code-AOB]
,a.[Buurtnaam]
,a.[Huisnummer]
,a.[Huisnummertoevoeging]
,a.[Postcode]
,a.[Identificatie-PND]
,a.[Geometrie]
,a.[Datum einde gebruik-AOB]
,a.[Einddatum-AOB]
,c.[DateValue]
,a.[Woonplaatsnaam]
,(SELECT COUNT(DISTINCT(b.[Identificatie-AOB]))
  FROM [Clean.VBO] as b
  WHERE b.[Datum ontstaan-AOB] <= c.[DateValue] 
  AND (b.[Gebruiksdoel] IN ('1', '111', '11141', '11161', '121', '131', '141', '151', '161', '181'))
  AND (b.[Status code-AOB] <> 82)  
  AND (b.[Datum einde gebruik-AOB] = '2999-01-01' OR b.[Datum einde gebruik-AOB] > c.[DateValue])

  ) 
  AS AantalWoningenInDeTijd
FROM [Clean.VBO] as a 
INNER JOIN [Clean.Peilkalender] as c
ON a.[Datum ontstaan-AOB] <= c.[DateValue]

答案 3 :(得分:1)

我不确定我是否了解您想要的内容,但是我想您可以通过稍微更改子查询来获得所需的内容:

(SELECT COUNT(DISTINCT(b.[Identificatie-AOB]))
  FROM [Clean.VBO] as b
  WHERE b.[Datum ontstaan-AOB] <= c.[DateValue] 
  AND (b.[Gebruiksdoel] IN ('1', '111', '11141', '11161', '121', '131', '141', '151', '161', '181'))
  AND (b.[Status code-AOB] <> 82)  
  AND (b.[Datum einde gebruik-AOB] = '2999-01-01' OR b.[Datum einde gebruik-AOB] > c.[DateValue])
  AND (b.[Woonplaatsnaam] = a.[Woonplaatsnaam]) AS AantalWoningenInDeTijd -- Extend the condition instead of grouping by
)

答案 4 :(得分:1)

我认为您的子查询需要按如下方式连接到原始表:

 (SELECT COUNT(DISTINCT(b.[Identificatie-AOB]))
 FROM [Clean.VBO] as b
 WHERE a.[Woonplaatsnaam] = b.[Woonplaatsnaam] //added this line
 AND [Datum ontstaan-AOB] <= c.[DateValue] 
 AND (b.[Gebruiksdoel] IN ('1', '111', '11141', '11161', '121', '131', '141', '151', 
'161', '181'))
 AND (b.[Status code-AOB] <> 82)  
 AND (b.[Datum einde gebruik-AOB] = '2999-01-01' OR b.[Datum einde gebruik-AOB] > c. [DateValue])
 GROUP BY b.[Woonplaatsnaam]) AS AantalWoningenInDeTijd

这称为Correlated Subquery,并通过count为原始表中的每一行返回join