SQL - 比较同一个表中的数据

时间:2014-02-25 15:56:43

标签: sql oracle oracle11g

我的下表包含以下列 -

ID-1,ID-2和ID-3 - 关键列

费率 - 根据上述ID显示产品费率

日期 - 暗示该费率适用的日期。

+-------+----------+-------------+----------+------------+
| ID-1  | ID-2     | ID-3        | Rate     |   Date     |
+-------+----------+-------------+----------+------------+
| 2000  | 1        | 100         | 50       | 12/30/2013 |
+-------+----------+-------------+----------+------------+
| 2000  | 1        | 100         | 75       | 10/11/2013 |
+-------+----------+-------------+----------+------------+
| 2000  | 1        | 100         | 100      | 12/15/2013 |
+-------+----------+-------------+----------+------------+
| 2000  | 2        | 100         | 50       | 10/30/2013 |
+-------+----------+-------------+----------+------------+
| 2000  | 2        | 100         | 75       | 10/11/2013 |
+-------+----------+-------------+----------+------------+
| 2000  | 2        | 100         | 100      | 09/15/2013 |
+-------+----------+-------------+----------+------------+
| 3000  | 2        | 200         | 25       | 1/1/2014   |
+-------+----------+-------------+----------+------------+
| 4000  | 2        | 100         | 100      | 12/1/2013  |
+-------+----------+-------------+----------+------------+
| 4000  | 1        | 200         | 75       | 1/1/2014   |
+-------+----------+-------------+----------+------------+
| 4000  | 2        | 100         | 25       | 11/1/2014  |
+-------+----------+-------------+----------+------------+

对于ID-1,ID-2和ID-3的每个组合,我想以下列格式输出最近2个最高费率 - 以前的费率 - 是第二个最近的日期的费率 当前汇率 - 是最近日期的汇率

+-------+----------+-------------+---------------+----------------+
| ID-1  | ID-2     | ID-3        | Previous Rate |  Current Rate  |
+-------+----------+-------------+---------------+----------------+
| 2000  | 1        | 100         | 100           | 50             |
+-------+----------+-------------+---------------+----------------+
| 2000  | 2        | 100         | 75            | 50             |
+-------+----------+-------------+---------------+----------------+
| 3000  | 2        | 200         |               | 25             |
+-------+----------+-------------+---------------+----------------+
| 4000  | 1        | 200         |               | 75             |
+-------+----------+-------------+---------------+----------------+
| 4000  | 2        | 200         | 25            | 100            |
+-------+----------+-------------+---------------+----------------+

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

也许是这样的?

select
  id-1,
  id-2,
  id-3,
  first_value(rate) over (partition by id-1, id-2, id-3 order by date desc) as current_rate
  lead(rate,1) over (partition by id-1, id-2, id-3 order by date desc) as prev_rate
from
  table

答案 1 :(得分:2)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE test ( "ID-1", "ID-2", "ID-3", Rate, "Date" ) AS
          SELECT 2000  , 1        , 100         , 50       , TO_DATE( '12/30/2013', 'MM/DD/YYYY' ) FROM DUAL
UNION ALL SELECT 2000  , 1        , 100         , 75       , TO_DATE( '10/11/2013', 'MM/DD/YYYY' ) FROM DUAL
UNION ALL SELECT 2000  , 1        , 100         , 100      , TO_DATE( '12/15/2013', 'MM/DD/YYYY' ) FROM DUAL
UNION ALL SELECT 2000  , 2        , 100         , 50       , TO_DATE( '10/30/2013', 'MM/DD/YYYY' ) FROM DUAL
UNION ALL SELECT 2000  , 2        , 100         , 75       , TO_DATE( '10/11/2013', 'MM/DD/YYYY' ) FROM DUAL
UNION ALL SELECT 2000  , 2        , 100         , 100      , TO_DATE( '09/15/2013', 'MM/DD/YYYY' ) FROM DUAL
UNION ALL SELECT 3000  , 2        , 200         , 25       , TO_DATE( '1/1/2014', 'MM/DD/YYYY' )   FROM DUAL
UNION ALL SELECT 4000  , 2        , 100         , 100      , TO_DATE( '12/1/2013', 'MM/DD/YYYY' )  FROM DUAL
UNION ALL SELECT 4000  , 1        , 200         , 75       , TO_DATE( '1/1/2014', 'MM/DD/YYYY' )   FROM DUAL
UNION ALL SELECT 4000  , 2        , 100         , 25       , TO_DATE( '11/1/2014', 'MM/DD/YYYY' )  FROM DUAL;

查询1

WITH rankings AS (
  SELECT "ID-1",
         "ID-2",
         "ID-3",
         Rate,
         DENSE_RANK() OVER (PARTITION BY "ID-1", "ID-2", "ID-3"
                            ORDER BY "Date" DESC, Rate DESC ) AS "Rank"
  FROM   test
)
SELECT "ID-1",
       "ID-2",
       "ID-3",
       MAX( CASE "Rank" WHEN 1 THEN Rate END ) AS current_rate,
       MAX( CASE "Rank" WHEN 2 THEN Rate END ) AS previous_rate
FROM   rankings
GROUP BY
       "ID-1",
       "ID-2",
       "ID-3"

<强> Results

| ID-1 | ID-2 | ID-3 | CURRENT_RATE | PREVIOUS_RATE |
|------|------|------|--------------|---------------|
| 2000 |    1 |  100 |           50 |           100 |
| 2000 |    2 |  100 |           50 |            75 |
| 3000 |    2 |  200 |           25 |        (null) |
| 4000 |    1 |  200 |           75 |        (null) |
| 4000 |    2 |  100 |           25 |           100 |

答案 2 :(得分:0)

这可能会对你有帮助。

SELECT id1, id2, id3, prev_rate, curr_rate
FROM(
     SELECT id1, 
            id2, 
            id3,
            rate AS curr_rate, 
            LEAD(rate,1) OVER (PARTITION BY id1, id2, id3 ORDER BY date DESC) AS prev_rate,
            DENSE_RANK() OVER (PARTITION BY id1, id2, id3 ORDER BY date DESC) AS rnk
     FROM   <table_name>
     )
WHERE rnk = 1;