SQL选择性分组

时间:2017-01-26 15:56:23

标签: sql

我在比较不同表格中的相关数据时遇到了一些麻烦,我将非常感谢您在下面的主题上获得一些帮助。不幸的是,我不确定DBS是什么(虽然没什么先例),但在IBM硬件上运行它。所以要简化数据集:

发票

Doci         Sumi
1005         10
1006         15
1007         7
1008         20

PAYMENTS

Docp        Sump
1006         -15
1005         -4
1005         -6
1007         -7

目的是比较两个表格并查看是否存在匹配 - 基本上是否已在付款中涵盖发票金额。对我来说,第一个新事物是比较另一个图表中负值的数值数据,但是让它与-1乘数一起工作。

我无法真正提出解决方案的剩余问题实质上是让查询理解记录/发票没有1005被覆盖,只有两个交易。基本上结果应该只是发票号1008,因为它在付款表中没有匹配。

我最终检查了SQL聚合函数,即SUM,但实际上并没有弄清楚如何利用它,因为我不想总结整个Sump列中的值,而只是那些具有相同记录的值Docp专栏。

到目前为止,我所拥有的是:

SELECT * from INVOICES
inner join PAYMENTS on INVOICES.Doci = PAYMENTS.Docp
where Sumi <> (Sump*-1)

所以,这个查询在某种程度上起作用,我不会在结果中得到1006和1007等记录,但我确实得到1005,因为看似值10被比作4而不是4 + 6。

非常感谢您的任何反馈!

4 个答案:

答案 0 :(得分:1)

您可以找到每个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

答案 1 :(得分: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 

结果:

Doci        Remaining
----------- ----------
1008        20

答案 2 :(得分: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都有匹配(即付款==发票)

答案 3 :(得分:0)

您需要将问题分解为几个步骤:

首先按照它的ID,Docp汇总付款。

select 
    Docp,
    SUM(Sump) as payment_sum
from PAYMENTS
group by Docp

让我们调用此查询的结果PAYMENT_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
    ;