Oracle SQL百分比差异相同列

时间:2017-11-23 01:55:24

标签: oracle12c

鉴于以下拍卖数据,您如何找到使用Oracle SQL的产品的最近和之前出价之间的百分比差异?

人A和B的重复序列(SEQ)代表我正在使用的数据。

非常感谢您的SQL示例。

TXN_TIME              | SEQ | PERSON | PRODUCT | TRANSACTION | BID  |
2017-11-22 15:41:10:0 | 20  | A      | 1       | BID         | 12   |
2017-11-22 15:35:10:0 | 10C | A      | 1       | CXLBID      | NULL |
2017-11-22 15:34:25:0 | 10  | A      | 1       | BID         | 10   |
2017-11-22 15:35:40:0 | 6   | A      | 2       | BID         | 4    |
2017-11-22 15:34:50:0 | 1C  | A      | 2       | CXLBID      | NULL |
2017-11-22 15:34:20:0 | 1   | A      | 2       | BID         | 5    |
2017-11-22 15:35:45:0 | 6   | B      | 2       | BID         | 2    |
2017-11-22 15:34:55:0 | 1C  | B      | 2       | CXLBID      | NULL |
2017-11-22 15:34:25:0 | 1   | B      | 2       | BID         | 1    |

2 个答案:

答案 0 :(得分:0)

如果可用,我们可以尝试使用LEAD / LAG分析功能。但是,这里的一种方法是使用CTE来识别每个人的最近和之前的出价,然后比较这两个值。

WITH cte AS (
    SELECT PERSON, BID,
        ROW_NUMBER() OVER (PARTITION BY PERSON ORDER BY TXN_TIME DESC) rn
    FROM yourTable
    WHERE TRANSACTION = 'BID'
)

SELECT
    t1.PERSON,
    100*(t1.BID - t2.BID) / t2.BID AS BID_PCT_DIFF
FROM cte t1
INNER JOIN cte t2
    ON t1.PERSON = t2.PERSON AND
       t1.rn = 1 AND t2.rn = 2;

enter image description here

此输出看起来正确,因为人A的出价为4到12,增加了8或200%,而人B的出价为1到2 ,这是100%的增长。

我在SQL Server中创建了一个演示,因为我总是很难让Oracle演示工作。但我的查询只是ANSI SQL,并且应该在SQL Server或Oracle上运行相同。

Demo

答案 1 :(得分:0)

您使用Oracle 12是件好事。这样您就可以使用MATCH_RECOGNIZE子句,这对您的问题非常有用。

我使用带有可选第二个参数的CHANGE函数计算MATCH_RECOGNIZE子句中的LAST()列,这是映射到特定模式的行集中的逻辑偏移量变量。我格式 CHANGE子句中的SELECT列 - 我使用了最喜欢的黑客,使用“货币”符号附加百分号...您可以修改格式你想要的任何方式,而不影响计算(隐藏在MATCH_RECOGNIZE子句中)。

with auction_data ( txn_time, seq, person, product, transaction, bid ) as (
 select timestamp '2017-11-22 15:41:10', '20' , 'A', 1, 'BID'   , 12   from dual union all
 select timestamp '2017-11-22 15:35:10', '10C', 'A', 1, 'CXLBID', NULL from dual union all
 select timestamp '2017-11-22 15:34:25', '10' , 'A', 1, 'BID'   , 10   from dual union all
 select timestamp '2017-11-22 15:35:40', '6'  , 'A', 2, 'BID'   , 4    from dual union all
 select timestamp '2017-11-22 15:34:50', '1C' , 'A', 2, 'CXLBID', NULL from dual union all
 select timestamp '2017-11-22 15:34:20', '1'  , 'A', 2, 'BID'   , 5    from dual union all
 select timestamp '2017-11-22 15:35:45', '6'  , 'B', 2, 'BID'   , 2    from dual union all
 select timestamp '2017-11-22 15:34:55', '1C' , 'B', 2, 'CXLBID', NULL from dual union all
 select timestamp '2017-11-22 15:34:25', '1'  , 'B', 2, 'BID'   , 1    from dual
)
-- End of simulated inputs (for testing only, not part of the solution).
select txn_time, seq, person, product, transaction, bid, 
       to_char( 100 * (change - 1), '999D0L', 'nls_currency=''%''') as change
from   auction_data
match_recognize(
  partition by person, product
  order     by txn_time
  measures  case when classifier() = 'B' then bid / last(B.bid, 1) end as change
  all rows per match
  pattern ( (B|A)* )
  define  B as B.transaction = 'BID'
);

TXN_TIME            SEQ PERSON    PRODUCT TRANSACTION        BID           CHANGE         
------------------- --- ------ ---------- ----------- ---------- ----------------
2017-11-22 15:34:25 10  A               1 BID                 10                 
2017-11-22 15:35:10 10C A               1 CXLBID                                 
2017-11-22 15:41:10 20  A               1 BID                 12            20.0%
2017-11-22 15:34:20 1   A               2 BID                  5                 
2017-11-22 15:34:50 1C  A               2 CXLBID                                 
2017-11-22 15:35:40 6   A               2 BID                  4           -20.0%
2017-11-22 15:34:25 1   B               2 BID                  1                 
2017-11-22 15:34:55 1C  B               2 CXLBID                                 
2017-11-22 15:35:45 6   B               2 BID                  2           100.0%