【问题标题】:Dense_rank query in sql(4 different columns) insql(4 不同列) 中的 Dense_rank 查询
【发布时间】:2018-05-17 17:40:14
【问题描述】:

我有一张如下表:

Sn no.  t_time              Value  rate  
ABC     17-MAY-18 08:00:00  100.00  3
ABC     17-MAY-18 22:00:00  200.00  1
ABC     16-MAY-18 08:00:00  100.00  1
XYZ     14-MAY-18 01:00:00  700.00  1
XYZ     15-MAY-18 10:00:00  500.00  2
XYZ     15-MAY-18 13:00:00  100.00  2

我想生成如下输出:

Sn no.     New_value
ABC        150
XYZ        450

Sn no.分组,New_value是每个日期值的最晚时间乘以rate,再取平均值。 例如 ABC new_value 是 平均值:[(100*1) 和 (200*1)]

它是一个大型数据集。如何以最有效的方式编写上述查询。请帮忙。

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    你可以使用解析函数(row_number())来实现结果

    SQL> WITH cte_table(Snno, t_time, Value, rate) AS (
      2    SELECT 'ABC', to_date('2018-05-17 08:00:00', 'YYYY-MM-DD HH24:MI:SS'), 100.00, 3 FROM DUAL UNION ALL
      3    SELECT 'ABC', to_date('2018-05-17 22:00:00', 'YYYY-MM-DD HH24:MI:SS'), 200.00, 1 FROM DUAL UNION ALL
      4    SELECT 'ABC', to_date('2018-05-16 08:00:00', 'YYYY-MM-DD HH24:MI:SS'), 100.00, 1 FROM DUAL UNION ALL
      5    SELECT 'XYZ', to_date('2018-05-14 01:00:00', 'YYYY-MM-DD HH24:MI:SS'), 700.00, 1 FROM DUAL UNION ALL
      6    SELECT 'XYZ', to_date('2018-05-15 10:00:00', 'YYYY-MM-DD HH24:MI:SS'), 500.00, 2 FROM DUAL UNION ALL
      7    SELECT 'XYZ', to_date('2018-05-15 13:00:00', 'YYYY-MM-DD HH24:MI:SS'), 100.00, 2 FROM DUAL),
      8    --------------------------------
      9    -- End of data preparation
     10    --------------------------------
     11  rn_table AS (
     12    SELECT t.*, row_number() OVER (PARTITION BY TRUNC(t_time) ORDER BY t_time DESC) AS rn
     13      FROM cte_table t)
     14  SELECT snno,
     15         AVG(VALUE * rate) new_value
     16    FROM rn_table
     17   WHERE rn = 1
     18   GROUP BY snno;
    

    输出:

    SNNO  NEW_VALUE
    ---- ----------
    ABC         150
    XYZ         450
    

    【讨论】:

      【解决方案2】:

      在子查询中使用ROW_NUMBER(或RANK/DENSE_RANK,如果更合适的话)解析函数,然后在外部查询中聚合:

      SQL Fiddle

      Oracle 11g R2 架构设置

      CREATE TABLE table_name ( Snno, t_time, Value, rate ) AS
      SELECT 'ABC', TIMESTAMP '2018-05-17 08:00:00', 100.00, 3 FROM DUAL UNION ALL
      SELECT 'ABC', TIMESTAMP '2018-05-17 22:00:00', 200.00, 1 FROM DUAL UNION ALL
      SELECT 'ABC', TIMESTAMP '2018-05-16 08:00:00', 100.00, 1 FROM DUAL UNION ALL
      SELECT 'XYZ', TIMESTAMP '2018-05-14 01:00:00', 700.00, 1 FROM DUAL UNION ALL
      SELECT 'XYZ', TIMESTAMP '2018-05-15 10:00:00', 500.00, 2 FROM DUAL UNION ALL
      SELECT 'XYZ', TIMESTAMP '2018-05-15 13:00:00', 100.00, 2 FROM DUAL;
      

      查询 1

      SELECT snno,
             AVG( value * rate ) As new_value
      FROM   (
        SELECT t.*,
               ROW_NUMBER() OVER (
                 PARTITION BY snno, value
                 ORDER BY t_time DESC
               ) AS rn
        FROM   table_name t
      )
      WHERE rn = 1
      GROUP BY snno
      

      Results

      | SNNO |         NEW_VALUE |
      |------|-------------------|
      |  ABC |               250 |
      |  XYZ | 633.3333333333334 |
      

      【讨论】:

        猜你喜欢
        • 2011-03-18
        • 2012-06-01
        • 2022-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-20
        相关资源
        最近更新 更多