Sql查询比较和求和

时间:2014-09-08 17:55:10

标签: sql sql-server sql-scripts

我有这些问题我需要匹配一列的总和,以查看它们是否与发票编号的发票的最终总数相匹配(我正在查询中执行此操作) 实施例

Invoice No      Line _no      Total Line  Invoice total   Field I will create
----------------------------------------------------------------------
45                 1            145            300              145
45                 2            165            300              300    Match

46                 1             200           200               200   Match  

47                 1             100           300               100
47                 2             100           300               200 
47                 3             100           300               300   Match

3 个答案:

答案 0 :(得分:4)

你想要一个累积总和。在SQL Server 2012+中,只需:

select e.*,
       (case when InvoiceTotal = sum(InvoiceTotal) over (partition by invoice_no order by line_no)
             then 'Match'
        end)
from example e;

在早期版本的SQL Server中,我倾向于使用相关的子查询:

select e.*
       (case when InvoiceTotal = (select sum(InvoiceTotal) 
                                  from example e2
                                  where e2.Invoice_no = e.invoice_no and
                                        e2.line_no >= e.line_no
                                 )
             then 'Match'
        end)
from example e;

你也可以使用{阿里建议的cross apply来做到这一点。

编辑:

现在我想到了这个问题,你不需要累积金额。这就是我最初想到的问题。因此,这将在SQL Server 2008中起作用:

select e.*,
       (case when InvoiceTotal = sum(InvoiceTotal) over (partition by invoice_no)
             then 'Match'
        end)
from example e;

如果没有更多操作,您无法获得累积总和(倒数第二列),但match列并不难。

答案 1 :(得分:2)

SQL Fiddle

MS SQL Server 2008架构设置

CREATE TABLE TEST(InvoiceNo INT, Line_no INT, TotalLine INT, InvoiceTotal INT)

INSERT INTO TEST VALUES 
(45 ,1 ,145 ,300),
(45 ,2 ,165 ,300),
(46 ,1 ,200 ,200),
(47 ,1 ,100 ,300),
(47 ,2 ,100 ,300),
(47 ,3 ,100 ,300)

查询1

SELECT  t.[InvoiceNo]
       ,t.[Line_no]
       ,t.[TotalLine]
       ,t.[InvoiceTotal]
       ,C.Grand_Total
       ,CASE WHEN C.Grand_Total = t.[InvoiceTotal] 
               THEN 'Match' ELSE '' END AS [Matched]
FROM TEST t
      CROSS APPLY (SELECT SUM([TotalLine]) AS Grand_Total
                   FROM TEST
                   WHERE [InvoiceNo] = t.[InvoiceNo]
                    AND  [Line_no] < = t.[Line_no]) C

<强> Results

| INVOICENO | LINE_NO | TOTALLINE | INVOICETOTAL | GRAND_TOTAL | MATCHED |
|-----------|---------|-----------|--------------|-------------|---------|
|        45 |       1 |       145 |          300 |         145 |         |
|        45 |       2 |       165 |          300 |         310 |         |
|        46 |       1 |       200 |          200 |         200 |   Match |
|        47 |       1 |       100 |          300 |         100 |         |
|        47 |       2 |       100 |          300 |         200 |         |
|        47 |       3 |       100 |          300 |         300 |   Match |

答案 2 :(得分:1)

这是你要找的吗?我认为子查询是你所要求的,但我猜测得到的结果与整个事情类似。

select t."Invoice No", t."Line no_", t."Invoice total", 
        calcTotals.lineNum as calcSum, case when t."Invoice total" = calcTotals.lineNum then 'matched' else 'not matched' end
from [table] t
inner join (
    select "Invoice No" as invoiceNumber,
        sum("Line _no") as lineNum
    from [table]
    group by "Invoice No"
) calcTotals on t."Invoice No" = calcTotals.invoiceNumber