子查询返回多个结果?
Subquery returning more than one result?
我运行这个查询:
SELECT
CAST(PolicyNumber AS varchar(50)) POLICYNUMBER,
CAST(EFFECTIVEDATE AS DATE) EFFECTIVEDATE ,
MAX(CAST(EXPIRATIONDATE AS DATE)) EXPIRATIONDATE,
CAST(ISSUINGCOMPANY AS varchar(4)) AS INSURER,
CAST(INSUREDLEGALNAME AS varchar(250)) AS INSUREDNAME,
PROGRAM,
MAX(CAST(CANCELDATE AS DATE)) AS CANCELDATE,
CAST(INSUREDADDR1 AS varchar(500)) AS INSUREDADDR1,
CAST(INSUREDADDR2 AS varchar(500)) AS INSUREDADDR2,
CAST(INSUREDCITY AS varchar(500)) AS INSUREDCITY,
CAST(INSUREDSTATE AS varchar(20)) AS INSUREDSTATE,
CAST(INSUREDZIP AS varchar(20)) AS INSUREDZIP ,
(SELECT SourceId FROM STG.[Source] WHERE [SystemName] = 'CRU') AS SOURCESYSTEMID
,(Select ProgramInclude = CASE WHEN ProgramInClude = 'Y' THEN 1 Else 0 END
From STG.LPT L INNER Join SRC.Policy C ON C.Program = L.ProgramCode ) AS LPT
FROM SRC.Policy
GROUP BY POLICYNUMBER,
EFFECTIVEDATE,
ISSUINGCOMPANY,
INSUREDLEGALNAME,
PROGRAM,
INSUREDADDR1,
INSUREDADDR2,
INSUREDCITY,
INSUREDSTATE,
INSUREDZIP
得到这个结果:
Msg 512, Level 16, State 1, Line 16
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Warning: Null value is eliminated by an aggregate or other SET operation.
有什么想法吗?
您的子查询应该 return 只有一行,因为它们是结果集的一部分。你可以做的是:
- 要么确保 WHERE 子句确保只有一行 returned
- 添加 TOP 1 子句以确保只有一行 returned。添加 TOP 子句时,请添加 ORDER BY 子句以确保您确定性地获取数据,而不是随机获取数据。因为我没有你的模式,所以我没有为子查询添加 ORDER BY
- 此外,您不需要在子查询中再加入一次。您可以在子查询
中引用外部策略table
SELECT
CAST(PolicyNumber AS varchar(50)) POLICYNUMBER,
CAST(EFFECTIVEDATE AS DATE) EFFECTIVEDATE ,
MAX(CAST(EXPIRATIONDATE AS DATE)) EXPIRATIONDATE,
CAST(ISSUINGCOMPANY AS varchar(4)) AS INSURER,
CAST(INSUREDLEGALNAME AS varchar(250)) AS INSUREDNAME,
PROGRAM,
MAX(CAST(CANCELDATE AS DATE)) AS CANCELDATE,
CAST(INSUREDADDR1 AS varchar(500)) AS INSUREDADDR1,
CAST(INSUREDADDR2 AS varchar(500)) AS INSUREDADDR2,
CAST(INSUREDCITY AS varchar(500)) AS INSUREDCITY,
CAST(INSUREDSTATE AS varchar(20)) AS INSUREDSTATE,
CAST(INSUREDZIP AS varchar(20)) AS INSUREDZIP ,
(SELECT TOP 1 SourceId FROM STG.[Source] WHERE [SystemName] = 'CRU') AS SOURCESYSTEMID
,(Select TOP 1 ProgramInclude = CASE WHEN ProgramInClude = 'Y' THEN 1 Else 0 END
From STG.LPT L WHERE L.ProgramCode = op.Program ) AS LPT
FROM SRC.Policy AS op
GROUP BY POLICYNUMBER,
EFFECTIVEDATE,
ISSUINGCOMPANY,
INSUREDLEGALNAME,
PROGRAM,
INSUREDADDR1,
INSUREDADDR2,
INSUREDCITY,
INSUREDSTATE,
INSUREDZIP
上面那个,你必须确保你的 TOP 子句 return 是正确的。否则,我会建议避免子查询和使用 JOINS 的另一种选择,正如我在下面提到的:
DECLARE @SourceId INT
-- Use either of the below approaches for populating @sourceId
SET @SourceId = (SELECT SourceId FROM STG.[Source] WHERE [SystemName] = 'CRU' ) -- Add additional WHERE clause to pickup right value or
SET @SourceId = (SELECT TOP 1 SourceId FROM STG.[Source] WHERE [SystemName] = 'CRU' ) -- Add additional ORDER BY clause.
SELECT
CAST(PolicyNumber AS varchar(50)) POLICYNUMBER,
CAST(EFFECTIVEDATE AS DATE) EFFECTIVEDATE ,
MAX(CAST(EXPIRATIONDATE AS DATE)) EXPIRATIONDATE,
CAST(ISSUINGCOMPANY AS varchar(4)) AS INSURER,
CAST(INSUREDLEGALNAME AS varchar(250)) AS INSUREDNAME,
PROGRAM,
MAX(CAST(CANCELDATE AS DATE)) AS CANCELDATE,
CAST(INSUREDADDR1 AS varchar(500)) AS INSUREDADDR1,
CAST(INSUREDADDR2 AS varchar(500)) AS INSUREDADDR2,
CAST(INSUREDCITY AS varchar(500)) AS INSUREDCITY,
CAST(INSUREDSTATE AS varchar(20)) AS INSUREDSTATE,
CAST(INSUREDZIP AS varchar(20)) AS INSUREDZIP ,
@SourceId AS SOURCESYSTEMID,
CASE WHEN ProgramInClude = 'Y' THEN 1 Else 0 END AS LPT
FROM SRC.Policy AS op
INNER JOIN STG.LPT L ON
L.ProgramCode = op.Program
GROUP BY POLICYNUMBER,
EFFECTIVEDATE,
ISSUINGCOMPANY,
INSUREDLEGALNAME,
PROGRAM,
INSUREDADDR1,
INSUREDADDR2,
INSUREDCITY,
INSUREDSTATE,
INSUREDZIP,
@SourceId AS SOURCESYSTEMID,
CASE WHEN ProgramInClude = 'Y' THEN 1 Else 0 END
我已经对自己做了一些修正,这是结果,现在 运行 很好。而且我没有使用 TOP 1
但更正了子查询中不必要的连接
感谢大家的帮助。
SELECT
CAST(PolicyNumber AS varchar(50)) POLICYNUMBER,
CAST(EFFECTIVEDATE AS DATE) EFFECTIVEDATE ,
MAX(CAST(EXPIRATIONDATE AS DATE)) EXPIRATIONDATE,
CAST(ISSUINGCOMPANY AS varchar(4)) AS INSURER,
CAST(INSUREDLEGALNAME AS varchar(250)) AS INSUREDNAME,
PROGRAM,
MAX(CAST(CANCELDATE AS DATE)) AS CANCELDATE,
CAST(INSUREDADDR1 AS varchar(500)) AS INSUREDADDR1,
CAST(INSUREDADDR2 AS varchar(500)) AS INSUREDADDR2,
CAST(INSUREDCITY AS varchar(500)) AS INSUREDCITY,
CAST(INSUREDSTATE AS varchar(20)) AS INSUREDSTATE,
CAST(INSUREDZIP AS varchar(20)) AS INSUREDZIP ,
(SELECT SourceId FROM STG.[Source] WHERE [SystemName] = 'CRU') AS SOURCESYSTEMID
,(Select ProgramInclude = CASE WHEN ProgramInClude = 'Y' THEN 1 Else 0 END
From STG.LPT L WHERE C.Program = L.ProgramCode ) AS LPT
FROM SRC.CRUPolicy C
GROUP BY POLICYNUMBER,
EFFECTIVEDATE,
ISSUINGCOMPANY,
INSUREDLEGALNAME,
PROGRAM,
INSUREDADDR1,
INSUREDADDR2,
INSUREDCITY,
INSUREDSTATE,
INSUREDZIP
我运行这个查询:
SELECT
CAST(PolicyNumber AS varchar(50)) POLICYNUMBER,
CAST(EFFECTIVEDATE AS DATE) EFFECTIVEDATE ,
MAX(CAST(EXPIRATIONDATE AS DATE)) EXPIRATIONDATE,
CAST(ISSUINGCOMPANY AS varchar(4)) AS INSURER,
CAST(INSUREDLEGALNAME AS varchar(250)) AS INSUREDNAME,
PROGRAM,
MAX(CAST(CANCELDATE AS DATE)) AS CANCELDATE,
CAST(INSUREDADDR1 AS varchar(500)) AS INSUREDADDR1,
CAST(INSUREDADDR2 AS varchar(500)) AS INSUREDADDR2,
CAST(INSUREDCITY AS varchar(500)) AS INSUREDCITY,
CAST(INSUREDSTATE AS varchar(20)) AS INSUREDSTATE,
CAST(INSUREDZIP AS varchar(20)) AS INSUREDZIP ,
(SELECT SourceId FROM STG.[Source] WHERE [SystemName] = 'CRU') AS SOURCESYSTEMID
,(Select ProgramInclude = CASE WHEN ProgramInClude = 'Y' THEN 1 Else 0 END
From STG.LPT L INNER Join SRC.Policy C ON C.Program = L.ProgramCode ) AS LPT
FROM SRC.Policy
GROUP BY POLICYNUMBER,
EFFECTIVEDATE,
ISSUINGCOMPANY,
INSUREDLEGALNAME,
PROGRAM,
INSUREDADDR1,
INSUREDADDR2,
INSUREDCITY,
INSUREDSTATE,
INSUREDZIP
得到这个结果:
Msg 512, Level 16, State 1, Line 16 Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. Warning: Null value is eliminated by an aggregate or other SET operation.
有什么想法吗?
您的子查询应该 return 只有一行,因为它们是结果集的一部分。你可以做的是:
- 要么确保 WHERE 子句确保只有一行 returned
- 添加 TOP 1 子句以确保只有一行 returned。添加 TOP 子句时,请添加 ORDER BY 子句以确保您确定性地获取数据,而不是随机获取数据。因为我没有你的模式,所以我没有为子查询添加 ORDER BY
- 此外,您不需要在子查询中再加入一次。您可以在子查询 中引用外部策略table
SELECT
CAST(PolicyNumber AS varchar(50)) POLICYNUMBER,
CAST(EFFECTIVEDATE AS DATE) EFFECTIVEDATE ,
MAX(CAST(EXPIRATIONDATE AS DATE)) EXPIRATIONDATE,
CAST(ISSUINGCOMPANY AS varchar(4)) AS INSURER,
CAST(INSUREDLEGALNAME AS varchar(250)) AS INSUREDNAME,
PROGRAM,
MAX(CAST(CANCELDATE AS DATE)) AS CANCELDATE,
CAST(INSUREDADDR1 AS varchar(500)) AS INSUREDADDR1,
CAST(INSUREDADDR2 AS varchar(500)) AS INSUREDADDR2,
CAST(INSUREDCITY AS varchar(500)) AS INSUREDCITY,
CAST(INSUREDSTATE AS varchar(20)) AS INSUREDSTATE,
CAST(INSUREDZIP AS varchar(20)) AS INSUREDZIP ,
(SELECT TOP 1 SourceId FROM STG.[Source] WHERE [SystemName] = 'CRU') AS SOURCESYSTEMID
,(Select TOP 1 ProgramInclude = CASE WHEN ProgramInClude = 'Y' THEN 1 Else 0 END
From STG.LPT L WHERE L.ProgramCode = op.Program ) AS LPT
FROM SRC.Policy AS op
GROUP BY POLICYNUMBER,
EFFECTIVEDATE,
ISSUINGCOMPANY,
INSUREDLEGALNAME,
PROGRAM,
INSUREDADDR1,
INSUREDADDR2,
INSUREDCITY,
INSUREDSTATE,
INSUREDZIP
上面那个,你必须确保你的 TOP 子句 return 是正确的。否则,我会建议避免子查询和使用 JOINS 的另一种选择,正如我在下面提到的:
DECLARE @SourceId INT
-- Use either of the below approaches for populating @sourceId
SET @SourceId = (SELECT SourceId FROM STG.[Source] WHERE [SystemName] = 'CRU' ) -- Add additional WHERE clause to pickup right value or
SET @SourceId = (SELECT TOP 1 SourceId FROM STG.[Source] WHERE [SystemName] = 'CRU' ) -- Add additional ORDER BY clause.
SELECT
CAST(PolicyNumber AS varchar(50)) POLICYNUMBER,
CAST(EFFECTIVEDATE AS DATE) EFFECTIVEDATE ,
MAX(CAST(EXPIRATIONDATE AS DATE)) EXPIRATIONDATE,
CAST(ISSUINGCOMPANY AS varchar(4)) AS INSURER,
CAST(INSUREDLEGALNAME AS varchar(250)) AS INSUREDNAME,
PROGRAM,
MAX(CAST(CANCELDATE AS DATE)) AS CANCELDATE,
CAST(INSUREDADDR1 AS varchar(500)) AS INSUREDADDR1,
CAST(INSUREDADDR2 AS varchar(500)) AS INSUREDADDR2,
CAST(INSUREDCITY AS varchar(500)) AS INSUREDCITY,
CAST(INSUREDSTATE AS varchar(20)) AS INSUREDSTATE,
CAST(INSUREDZIP AS varchar(20)) AS INSUREDZIP ,
@SourceId AS SOURCESYSTEMID,
CASE WHEN ProgramInClude = 'Y' THEN 1 Else 0 END AS LPT
FROM SRC.Policy AS op
INNER JOIN STG.LPT L ON
L.ProgramCode = op.Program
GROUP BY POLICYNUMBER,
EFFECTIVEDATE,
ISSUINGCOMPANY,
INSUREDLEGALNAME,
PROGRAM,
INSUREDADDR1,
INSUREDADDR2,
INSUREDCITY,
INSUREDSTATE,
INSUREDZIP,
@SourceId AS SOURCESYSTEMID,
CASE WHEN ProgramInClude = 'Y' THEN 1 Else 0 END
我已经对自己做了一些修正,这是结果,现在 运行 很好。而且我没有使用 TOP 1
但更正了子查询中不必要的连接
感谢大家的帮助。
SELECT
CAST(PolicyNumber AS varchar(50)) POLICYNUMBER,
CAST(EFFECTIVEDATE AS DATE) EFFECTIVEDATE ,
MAX(CAST(EXPIRATIONDATE AS DATE)) EXPIRATIONDATE,
CAST(ISSUINGCOMPANY AS varchar(4)) AS INSURER,
CAST(INSUREDLEGALNAME AS varchar(250)) AS INSUREDNAME,
PROGRAM,
MAX(CAST(CANCELDATE AS DATE)) AS CANCELDATE,
CAST(INSUREDADDR1 AS varchar(500)) AS INSUREDADDR1,
CAST(INSUREDADDR2 AS varchar(500)) AS INSUREDADDR2,
CAST(INSUREDCITY AS varchar(500)) AS INSUREDCITY,
CAST(INSUREDSTATE AS varchar(20)) AS INSUREDSTATE,
CAST(INSUREDZIP AS varchar(20)) AS INSUREDZIP ,
(SELECT SourceId FROM STG.[Source] WHERE [SystemName] = 'CRU') AS SOURCESYSTEMID
,(Select ProgramInclude = CASE WHEN ProgramInClude = 'Y' THEN 1 Else 0 END
From STG.LPT L WHERE C.Program = L.ProgramCode ) AS LPT
FROM SRC.CRUPolicy C
GROUP BY POLICYNUMBER,
EFFECTIVEDATE,
ISSUINGCOMPANY,
INSUREDLEGALNAME,
PROGRAM,
INSUREDADDR1,
INSUREDADDR2,
INSUREDCITY,
INSUREDSTATE,
INSUREDZIP