在sql(4个不同的列)中的Dense_rank查询

时间:2018-05-17 08:28:36

标签: sql oracle

我有一张表格如下:

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是每个日期值的最新时间乘以速率,然后一起平均。 例如,ABC new_value是 平均值:[(100 * 1)和(200 * 1)]

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

在子查询中使用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 |