SQL选择性分组

SQL选择性分组,sql,Sql,我在比较不同表格中的相关数据时遇到了一些问题,如果能在下面的主题上获得帮助,我将不胜感激。不幸的是,我不确定DBS是什么,虽然它不是最先进的,但在IBM硬件上运行它。因此,为了简化数据集: 发票 Doci Sumi 1005 10 1006 15 1007 7 1008 20 付款 Docp Sump 1006 -15 1005 -4 1005 -6 1

我在比较不同表格中的相关数据时遇到了一些问题,如果能在下面的主题上获得帮助,我将不胜感激。不幸的是,我不确定DBS是什么,虽然它不是最先进的,但在IBM硬件上运行它。因此,为了简化数据集:

发票

Doci         Sumi
1005         10
1006         15
1007         7
1008         20
付款

Docp        Sump
1006         -15
1005         -4
1005         -6
1007         -7
其目的是比较两个表,看看是否有匹配-基本上是发票金额是否已包含在付款中。对我来说,第一件新事情是比较另一张图表中负值的数值数据,但是让它与-1乘数一起工作

剩下的问题,我真的想不出一个解决方案,基本上是让查询理解记录/发票编号1005被覆盖,只有两个事务。基本上,结果应仅为第1008号发票,因为它在付款表中没有匹配项

最后我确实回顾了SQL聚合函数,也就是SUM,但是我真的没有弄清楚如何使用它,因为我不想在整个油底壳列中汇总值,而只想在Docp列中汇总那些具有相同记录的值

到目前为止,我得到的是:

SELECT * from INVOICES
inner join PAYMENTS on INVOICES.Doci = PAYMENTS.Docp
where Sumi <> (Sump*-1)
因此,这个查询的工作范围是,我不会在结果中得到1006和1007这样的记录,但我得到了1005,因为看起来值10与4相比,而不是4+6


非常感谢您的反馈

您可以找到每个docp的总池,然后根据doc和sum将其与发票表连接起来

select i.* from invoices i
inner join (
    select
        docp,
        sum(sump) sump
    from payments
    group by docp
) p on i.doci = p.docp
and i.sumi + p.sump <> 0

试试这个,它只会给你一个额外的数量

declare @inv  table (Doci int, Sumi decimal)
insert @inv values (1005, 10), (1006, 15), (1007, 7), (1008, 20)

declare @pmt  table (Docp  int, Sump decimal)
insert @pmt values (1005, -4), (1006, -15), (1007, -7), (1005, -6)

;with payments(doc, amt)
as (
    select Docp, sum(Sump)
    from @pmt 
    group by Docp
)
select Doci, Sumi + isnull(amt,0) as Remaining
from @inv
left outer join payments p on p.doc = Doci 
where (Sumi + isnull(amt,0)) <> 0 

我分两步做的必须将其分组,以确定是否存在多次付款,以及是否平衡了发票:

SELECT doci, sumi, docp, sum(sump) as Sump INTO #Step1
from #INVOICES
inner join PAYMENTS on INVOICES.Doci = PAYMENTS.Docp
GROUP BY
doci, sumi, docp

GO

SELECT * from INVOICES
inner join #PAYMENTS on #INVOICES.Doci = #PAYMENTS.Docp
where Sumi <> (Sump*-1) AND doci NOT IN (select doci from #step1 WHERE sumi+Sump = 0)
结果是一个空数据集,因为它只返回付款不足以支付发票金额或金额过大的值


示例中的所有ID都有匹配项,即付款==发票

您需要将问题分解为以下步骤:

首先,按其id Docp对付款进行合计

select 
    Docp,
    SUM(Sump) as payment_sum
from PAYMENTS
group by Docp
让我们调用这个查询的结果PAYMENT\u SUM

然后将其与发票进行比较

select 
    I.Doci,
    I.sumi + P.payment_sum as diff
from INVOICES I
left join PAYMENT_SUM P
on I.Doci = P.Docp
;
这将为您提供以下结果:

Doci diff 
1005 0 
1006 0 
1007 0 
1008 null 
现在查看这个结果,您可以向查询中添加一个子句来选择所需内容。 若要在付款端选择完全不匹配的发票,则将使用子句

where P.Docp is null
或者,如果您还希望获得付款匹配但金额未完全覆盖的发票,则:

where (P.Docp is null) or ((I.sumi + P.payment_sum) <> 0)
现在,要组合所有步骤:

    select 
        I.Doci,
        I.sumi + P.payment_sum as diff
    from INVOICES as I
    left join (
        select 
            Docp,
            SUM(Sump) as payment_sum
        from PAYMENTS
        group by Docp
    )   as P
    on I.Doci = P.Docp

    where (P.Docp is null) or (I.sumi + P.payment_sum) <> 0
    ;

仔细想想,我真的不清楚你想要的结果
    select 
        I.Doci,
        I.sumi + P.payment_sum as diff
    from INVOICES as I
    left join (
        select 
            Docp,
            SUM(Sump) as payment_sum
        from PAYMENTS
        group by Docp
    )   as P
    on I.Doci = P.Docp

    where (P.Docp is null) or (I.sumi + P.payment_sum) <> 0
    ;