【问题标题】:oracle11g sql to find difference between rows from the same tableoracle11g sql查找同一表中行之间的差异
【发布时间】:2012-09-03 07:24:06
【问题描述】:

我有一个表 SAMPLE,其中包含唯一列(sal_id、gal_id)和金额、税款、日期和更多列。

示例表

 actual_id, sal_id, gal_id, processed_flag, amount, tax     date    
   1          101     201     Y             10       1     25-Aug-12  
   2          101     201     Y             20       3     27-Aug-12  
   3          101     201     N             15       2     29-Aug-12  

现在我需要找出最大日期的未处理数据 (process_flag='N') 和继续数据 (process_flag='Y') 之间的区别。我需要计算 (sal_id + gal_id) 组合的金额和税金之间的差异。

所以查询返回应该是这样的:

在此示例中,由于对于 (101, 201),我们有 2 个已处理的行,并且 (actual_id 2 具有最大日期。因此需要找到 actual_id 3 和 actual_id 2 行之间的差异。

actual_id,  sal_id,  gal_id, total_amount, total_tax  date    
    3          101     201    -5 (15-20)    -1 (2-3)   29-Aug-12   

我正在使用 Oracle 11g。请帮帮我。

【问题讨论】:

  • 您将如何处理这笔金额?减去未处理的 - 处理,反之亦然?你是什​​么意思sal_id + gal_id?结合两个ID?还是参考表的值?
  • 需要计算(未处理金额-已处理金额)和(未处理税-已处理税)。结合actual_id、sal_id、gal_id、日期形成SAMPLE表的唯一ID。

标签: sql group-by oracle11g


【解决方案1】:

试试这个:

WITH t AS (SELECT DISTINCT "sal_id" sid,"gal_id" gid,"processed_flag" pf, max("amount") over
(partition BY "sal_id","gal_id","processed_flag") am,
max("tax") over
(partition BY "sal_id","gal_id","processed_flag") tx,
           max("actual_id") over
(partition BY "sal_id","gal_id","processed_flag") aid,
           max("date") over
(partition BY "sal_id","gal_id","processed_flag") dt
FROM sample)
SELECT t1.aid, t1.sid, t1.gid, t1.am-t2.am, t1.tx-t2.tx, t1.dt FROM t t1 JOIN t t2 ON t1.sid=t2.sid AND t1.gid=t2.gid
WHERE t1.pf='N' AND t2.pf='Y';

Here 是个小提琴


更新: 上一个答案假设 max(date) 也有 max(amount)。
一个更好的解决方案可以是:

WITH t AS (SELECT *
FROM sample s
WHERE s."date" = (SELECT max("date") FROM sample s_in
                WHERE s_in."sal_id" = s."sal_id"
                AND s_in."gal_id" = s."gal_id"
                AND s_in."processed_flag" = s."processed_flag"))
SELECT t1."actual_id", t1."sal_id", t1."gal_id", t1."amount"-t2."amount" total_amount, t1."tax"-t2."tax" total_tax, t1."date"
FROM t t1 JOIN t t2 ON t1."sal_id"=t2."sal_id" AND t1."gal_id"=t2."gal_id"
WHERE t1."processed_flag"='N' AND t2."processed_flag"='Y';

Here 是小提琴

【讨论】:

  • 谢谢@A.B.Cade。它按我预期的方式工作。非常感谢。由于我们使用了这么多分区,查询的性能如何?
  • 嗨 Cade.. 我在结果查询中也需要实际 ID。我通过添加“actual_id”aaa 修改了一个查询。但在结果查询中获得了两行。请帮助我修改查询。
  • 但是你有actual_id(别名为aid)。这是别名字段sqlfiddle.com/#!4/fc505/15 后的小提琴。顺便说一句,开始考虑它,我的回答假设 max(tax) 将具有 max(date) 这可能不是真的......
  • 是的@Cade..你是对的.. max(tax) 没有必要有 max(date)。在我的例子中,我就是这样给出的。只需要考虑 max(date) 。修改了我的表格数据以便更好地理解..
  • 伟大的@Cade。这正是我想要的。你能解释一下查询中的一部分吗? SELECT * FROM sample s WHERE s."date" = (SELECT max("date") FROM sample s_in WHERE s_in."sal_id" = s."sal_id" AND s_in."gal_id" = s."gal_id" AND s_in."processed_flag" = s."processed_flag") .. 当我们说两个 processes_flag 相等时,它如何返回第一行(标志 Y)和第三行(标志 N)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
  • 2016-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多