对来自不同查询的结果求和

时间:2016-05-07 14:43:33

标签: sql sql-server

我需要总结三个不同查询的结果。这是我正在做的事,但结果不正确。如果我单独运行每个查询它们都很好,但是将它们一起运行我会得到不同的结果。

select 'Inforce TIV',
ISNULL(SUM(a.TSI), 0)
+
ISNULL(SUM(b.TSI), 0)
+
ISNULL(SUM(c.TSI), 0)
from
(
    select ISNULL(SUM(p.[Suma Asegurada Inforce]), 0) as TSI
    from temp_portafolio_cy p
    --where p.fec_emi between @varFechaDesde and @varFechaHasta
    where p.fec_emi between '20160101' and '20160131'
    and p.sn_bancaseguros = 0
    group by p.cod_suc, p.cod_ramo_comercial, p.Poliza, p.Item
) a,
(
    select ISNULL(p.[Suma Asegurada Inforce], 0) as TSI
    from temp_portafolio_cy p
    --where p.fec_emi between @varFechaDesde and @varFechaHasta
    where p.fec_emi between '20160101' and '20160131'
    and p.sn_bancaseguros = -1
    and not (
        (p.cod_suc = 1 and p.cod_ramo_comercial = 34 and p.Poliza = 51385)
        or (p.cod_suc = 1 and p.cod_ramo_comercial = 26 and p.Poliza = 53231)
    )
    group by p.cod_suc, p.cod_ramo_comercial, p.Poliza, p.Item, p.[Suma Asegurada Inforce]
) b,
(
    select ISNULL(p.[Suma Asegurada], 0) as TSI
    from temp_portafolio_cy p
    --where p.fec_emi between @varFechaDesde and @varFechaHasta
    where p.fec_emi between '20160101' and '20160131'
    and p.sn_bancaseguros = -1
    and (
        (p.cod_suc = 1 and p.cod_ramo_comercial = 34 and p.Poliza = 51385)
        or (p.cod_suc = 1 and p.cod_ramo_comercial = 26 and p.Poliza = 53231)
    )
    group by p.cod_suc, p.cod_ramo_comercial, p.Poliza, p.Item, p.[Suma Asegurada]
) c

3 个答案:

答案 0 :(得分:0)

子查询中的group by可能会导致您在结果上获得笛卡尔联接,即通过乘法导致错误的求和。也许你可以这样写?

select 'Inforce TIV',
ISNULL(SUM(a.TSI), 0)
+
ISNULL(SUM(b.TSI), 0)
+
ISNULL(SUM(c.TSI), 0)
from
(
    select ISNULL(SUM(p.[Suma Asegurada Inforce]), 0) as TSI
    from temp_portafolio_cy p
    --where p.fec_emi between @varFechaDesde and @varFechaHasta
    where p.fec_emi between '20160101' and '20160131'
    and p.sn_bancaseguros = 0
) a,
(
    select ISNULL(p.[Suma Asegurada Inforce], 0) as TSI
    from temp_portafolio_cy p
    --where p.fec_emi between @varFechaDesde and @varFechaHasta
    where p.fec_emi between '20160101' and '20160131'
    and p.sn_bancaseguros = -1
    and not (
        (p.cod_suc = 1 and p.cod_ramo_comercial = 34 and p.Poliza = 51385)
        or (p.cod_suc = 1 and p.cod_ramo_comercial = 26 and p.Poliza = 53231)
    )
) b,
(
    select ISNULL(p.[Suma Asegurada], 0) as TSI
    from temp_portafolio_cy p
    --where p.fec_emi between @varFechaDesde and @varFechaHasta
    where p.fec_emi between '20160101' and '20160131'
    and p.sn_bancaseguros = -1
    and (
        (p.cod_suc = 1 and p.cod_ramo_comercial = 34 and p.Poliza = 51385)
        or (p.cod_suc = 1 and p.cod_ramo_comercial = 26 and p.Poliza = 53231)
    )
) c

答案 1 :(得分:0)

您正在对3组结果进行笛卡尔连接。 您有两个选择:

  1. 删除所有“分组依据”语句
  2. 在3个选择语句的每个语句中包含您的分组列,然后在将它们连接在一起时添加where子句(例如,其中a.code_suc = b.code_suc和b.code_suc = c.code_suc ...等等。 )
  3. 我建议使用选项1,因为在你给出的例子中并没有真正需要“group by”,并且where where子句会给你一个隐式的内连接

答案 2 :(得分:0)

您的查询正在创建三个独立子查询(a,b,c)的交叉连接,如果任何子查询返回多行,则会生成相当有趣的结果。

有多种方法可以更正您的查询。让我建议下面的那个消除子查询中对GROUP BY的需要,并且总体上简化了查询。 (顺便说一句,如果子查询永远不会返回空TSI值,您可以将结果列简化为ISNULL(SUM(TSI),0)。)

select 'Inforce TIV',
ISNULL(SUM(ISNULL(TSI, 0)), 0)
FROM (
    select p.[Suma Asegurada Inforce] as TSI
    from temp_portafolio_cy p
    --where p.fec_emi between @varFechaDesde and @varFechaHasta
    where p.fec_emi between '20160101' and '20160131'
    and p.sn_bancaseguros = 0

    UNION ALL

    select p.[Suma Asegurada Inforce]
    from temp_portafolio_cy p
    --where p.fec_emi between @varFechaDesde and @varFechaHasta
    where p.fec_emi between '20160101' and '20160131'
    and p.sn_bancaseguros = -1
    and not (
        (p.cod_suc = 1 and p.cod_ramo_comercial = 34 and p.Poliza = 51385)
        or (p.cod_suc = 1 and p.cod_ramo_comercial = 26 and p.Poliza = 53231)
    )

    UNION ALL

    select p.[Suma Asegurada]
    from temp_portafolio_cy p
    --where p.fec_emi between @varFechaDesde and @varFechaHasta
    where p.fec_emi between '20160101' and '20160131'
    and p.sn_bancaseguros = -1
    and (
        (p.cod_suc = 1 and p.cod_ramo_comercial = 34 and p.Poliza = 51385)
        or (p.cod_suc = 1 and p.cod_ramo_comercial = 26 and p.Poliza = 53231)
    )
) x