简体   繁体   中英

Sql Query Compare and Sum

I have these problem I need to match the sum a columns to see if they match with the Final Total of the Invoice by Invoice Number ( I am working in a query to do it) Example

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

You want a cumulative sum. In SQL Server 2012+, just do:

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

In earlier versions of SQL Server, I would be inclined to do it with a correlated subquery:

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;

You can also do this with a cross apply as M Ali suggests.

EDIT:

Now that I think about the problem, you don't need a cumulative sum. That was just how I originally thought of the problem. So, this will work in SQL Server 2008:

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

You can't get the cumulative sum out (the second to last column) without more manipulation, but the match column is not hard.

SQL Fiddle

MS SQL Server 2008 Schema Setup :

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)

Query 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 |

Is this what you're looking for? I think subquery is what you're asking about, but i'm guessing to get an end result similar to the entire thing.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM