从一个列值上的两个比较列 sum() 聚合返回一个 SQL 表
Posted
技术标签:
【中文标题】从一个列值上的两个比较列 sum() 聚合返回一个 SQL 表【英文标题】:Returning a SQL table from two compared column sum() aggregates on one column value 【发布时间】:2016-10-06 11:03:12 【问题描述】:我有一个工作查询,它与自身进行比较以查找具有非零差异的行。这将删除数据库中具有相同 rxid 并且它们的差异(付费 - 义务)分别为 x 和 -x 的条目。
我认为我需要使用的是聚合函数,因为如果有超过 2 个相同 ID 但具有平衡差异(例如三个差异为:x,-),我目前拥有的不会删除多个条目x/2,-x/2)。
我尝试使用 sum() 来获取每个 rxid 的整个列的总数,但我无法成功返回该行,因为我返回的内容“不是聚合函数的一部分”。有人告诉我使用游标,但我觉得这是关系数据库不可或缺的一部分,我在这里遗漏了一些东西。
WITH x
AS (
SELECT IsInstyRxFlag
,pri.payerReceiptItemId
,CONVERT(VARCHAR, rx.oeDate, 101) rxOeDate
,CONVERT(DECIMAL(6, 2), drx.payerOblig) payerObligation
,CONVERT(DECIMAL(6, 2), pri.amountPaid) amountPaid
,pri.rxId
,CONVERT(DECIMAL(6, 2), (pri.amountPaid - drx.payerOblig)) difference
,rxeventid
FROM PayerReceiptItem pri
JOIN Rx ON rx.rxId = pri.rxId
JOIN DispenseRx drx ON rx.rxId = drx.rxId
WHERE CONVERT(DECIMAL(6, 2), drx.payerOblig) <> CONVERT(DECIMAL(6, 2), pri.amountPaid)
AND payerReceiptID = 19781
)
SELECT x.*
FROM x
WHERE NOT EXISTS (
SELECT *
FROM x AS y
WHERE x.amountpaid = - 1 * y.amountpaid
AND x.difference = x.amountpaid
AND x.rxid = y.rxid
);
在这张图片中,我们看到我们有两个相似的 RXIDS 45.00。有一个 90 和另一个 -90 在此之外被删除,但我的 sql 代码不考虑总和。
我一直在处理的是一个查询,它返回 RXID 的总和及其义务和支付的金额。我坚持使用存在或其他东西来检查 payeroblig amountpaid 的区域。
select pri.RxID, (select SUM(drx.PAYEROBLIG) from Dispenserx drx where drx.RxID = pri.RxID) as payeroblig, (select SUM(pri1.AmountPaid) from PayerReceiptItem pri1 where pri1.RxID = pri.RxID and pri1.PayerReceiptID = 19781) as amountpaid from PayerReceipt pr
join PayerReceiptItem pri on pri.PayerReceiptID = pr.PayerReceiptID
JOIN DispenseRx drx ON pri.rxId = drx.rxId
where pr.PayerReceiptID=19781
让我们使用上面的代码,然后返回一个我们想要关注的 RXID。这有一个与已支付金额不同的付款人义务。这是该列中所有 RXID 的总和。这是一个问题,他们需要平衡,这会突出他们不匹配这个 RXID
【问题讨论】:
在上面的编辑中上传。 好的,我看到了你在得到的结果中的意思,我看到它们都有不同的 ReceiptItemId。我不明白的是你想要得到什么结果。 我想删除例如 RXID=3349796 的条目。如果我的 RXID 为 3349796 且相差 +45,我只能使用上面的第一组代码执行此操作。这抵消了其他两个并留下了平衡问题。我需要的是添加一个 rxID = 3349796 但相差 +90。这需要抵消两个-45的差异。 【参考方案1】:如果您想返回 差的总和 与 amountPaid 的总和 不同的所有行,我想这应该可以解决问题(未经测试) :
WITH x
AS (
SELECT IsInstyRxFlag
,pri.payerReceiptItemId
,CONVERT(VARCHAR, rx.oeDate, 101) rxOeDate
,CONVERT(DECIMAL(6, 2), drx.payerOblig) payerObligation
,CONVERT(DECIMAL(6, 2), pri.amountPaid) amountPaid
,pri.rxId
,CONVERT(DECIMAL(6, 2), (pri.amountPaid - drx.payerOblig)) difference
,rxeventid
FROM PayerReceiptItem pri
JOIN Rx ON rx.rxId = pri.rxId
JOIN DispenseRx drx ON rx.rxId = drx.rxId
WHERE CONVERT(DECIMAL(6, 2), drx.payerOblig) <> CONVERT(DECIMAL(6, 2), pri.amountPaid)
AND payerReceiptID = 19781
)
SELECT x.*
FROM x
WHERE EXISTS (
SELECT *
FROM x AS y
WHERE y.rxId = x.rxId
GROUP BY y.rxId
HAVING SUM(y.amountpaid) <> SUM(y.difference)
);
【讨论】:
【参考方案2】:我猜这个帖子的答案是这样的:
select distinct rxid, * from (select pri.RxID, (select SUM(drx.PAYEROBLIG) from Dispenserx drx where drx.RxID = pri.RxID) as Sumpayeroblig, (select SUM(pri1.AmountPaid) from PayerReceiptItem pri1 where pri1.RxID = pri.RxID and pri1.PayerReceiptID = 19781) as Sumamountpaid from PayerReceipt pr
join PayerReceiptItem pri on pri.PayerReceiptID = pr.PayerReceiptID
JOIN DispenseRx drx ON pri.rxId = drx.rxId
where pr.PayerReceiptID=19781) x
where x.Sumamountpaid <> x.Sumpayeroblig
这会获取两个表的总和,然后再次使用列名检查自身。这将返回 9 行。
【讨论】:
以上是关于从一个列值上的两个比较列 sum() 聚合返回一个 SQL 表的主要内容,如果未能解决你的问题,请参考以下文章