子查询返回多个结果?

时间:2020-05-13 08:24:13

标签: sql sql-server tsql ssms-2016

我运行以下查询:

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

并获得以下结果:

信息512,级别16,状态1,第16行 子查询返回的值超过1。当子查询遵循=,!=,<,<=,>,> =或将子查询用作表达式时,不允许这样做。 警告:空值已通过聚合或其他SET操作消除。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

您的子查询应该只返回一行,因为它们是结果集中的一部分。您可以做的是:

  • 确保WHERE子句确保仅返回一行
  • 添加TOP 1子句以确保仅返回一行。添加TOP子句时,请添加ORDER BY子句以确保确定性地获取数据,而不是随机获取数据。因为我没有您的架构,所以我没有为子查询添加ORDER BY
  • 您也不需要在子查询中再加入一次。您可以在子查询中引用外部Policy表
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子句返回正确的一个。否则,我将建议另一个避免子查询和使用JOINS的选项,如下所述:

{{1}}

答案 1 :(得分:0)

我对自己进行了一些修改,结果是这样,现在运行良好。而且我没有使用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
相关问题