Sql 查询比较和求和
Posted
技术标签:
【中文标题】Sql 查询比较和求和【英文标题】:Sql Query Compare and Sum 【发布时间】:2014-09-08 17:55:09 【问题描述】:我有这些问题我需要匹配总和列以查看它们是否与发票编号的发票最终总计匹配(我正在查询中执行此操作) 示例
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
【问题讨论】:
您只需要每张发票的总和来匹配发票总额还是需要展示您的工作?如果展示你的作品,你想用total_line的语法总和超过发票号。运行总数Example 您运行的是什么版本的 SQL Server? 我需要创建一个新列,并在对行求和时查看发票总额是否匹配,并查看所有发票是否匹配 【参考方案1】:你想要一个累积的总和。在 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;
您也可以按照 M Ali 的建议使用 cross apply
来执行此操作。
编辑:
现在我考虑了这个问题,您不需要累积总和。这正是我最初想到这个问题的方式。所以,这将在 SQL Server 2008 中工作:
select e.*,
(case when InvoiceTotal = sum(InvoiceTotal) over (partition by invoice_no)
then 'Match'
end)
from example e;
如果不进行更多操作,您无法得出累积总和(倒数第二列),但 match
列并不难。
【讨论】:
你的第一个解决方案看起来很漂亮,但它会抛出一个错误,请修复它,我很想学习这个语法:)SQL FIDDLE
,因为我不知道该怎么做,所以我找不到错误.
@M.Ali 你没有选择 SQL Server 2012。
@MartinSmith SUM() Over Partition by ...。我以为它在 2008 年就得到了支持,不是吗?
@M.Ali 和order by
做的跑分不是。
干杯 @MartinSmith 我在 2012 年工作不多,因此不知道这一点。我以为我错过了一些东西,因为错误消息没有说Not supported function used
,它只是说error near order by
。不过感谢您的建议。【参考方案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 |
【讨论】:
而且,作为对未来的参考,如果您为了成为第一个而发布了一个不完整的答案,那么如果您得到了后来 不是的反对票,请不要感到惊讶 当您决定更新答案时已更正(就像这次一样) 我不需要这样做。另一方面,如果您要称投票者为“小丑”,那么您确实需要发布完整的答案,否则您只是在抱怨 @M.Ali 与往常一样,您似乎认为投反对票在某种程度上是禁忌。如果我不喜欢你的回答,我会投反对票。这就是downvoting的工作原理。我不能发表评论并等待看看你是否改变你的答案。如果您不想被否决,请提供完整的答案。人们可以出于他们选择的任何原因对您投反对票。 @M.Ali 几点建议:(1) 不要急于发布答案。这就是为什么它们通常是不完整的、猜测的或其他值得否决的原因。 (2)不要如此个人地取消投票。它们是关于内容的,而不是关于你的。 (3) 不要开始人身攻击。如果您修复了 (1) 和 (2),您将永远不必到达 (3)。 @M.Ali 当您将鼠标悬停在向下箭头上进行投票时,如果您的第一个版本未能包含 OP 想要的列,它会显示 此答案没有用投反对票是完全可以接受的。答案不一定是错误的才能获得反对票。【参考方案3】:这就是你要找的吗?我认为子查询是您要问的,但我猜想得到与整个事情相似的最终结果。
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
【讨论】:
非常感谢你救了我的命 :)以上是关于Sql 查询比较和求和的主要内容,如果未能解决你的问题,请参考以下文章