对关联数组pl / sql中的值进行排序

时间:2015-04-12 11:52:56

标签: sorting plsql oracle11g associative-array

如果ID是偶数,我必须对与该ID DESC对应的值进行排序,如果ID为奇数,我必须对值ASC进行排序。这是一个名为Grades的表。

   ID|COL1|COL2|COL3|COL4|COL5|COL6|COL7|  
   1 | 6  | 3  | 8  | 4  | 7  | 8  | 4  |  
   2 | 5  | 7  | 9  | 2  | 1  | 7  | 8  |  
   3 | 2  | 7  | 4  | 8  | 1  | 5  | 9  |  
   4 | 8  | 4  | 7  | 9  | 4  | 1  | 4  |  
   5 | 7  | 5  | 2  | 5  | 2  | 6  | 4  |

结果必须是:

  ID|COL1|COL2|COL3|COL4|COL5|COL6|COL7| 
  1 | 3  | 4  | 4  | 6  | 7  | 8  | 8  | 
  2 | 9  | 8  | 7  | 7  | 5  | 2  | 1  | 
  3 | 1  | 2  | 4  | 5  | 7  | 8  | 9  | 
  4 | 9  | 8  | 7  | 4  | 4  | 4  | 1  | 
  5 | 2  | 2  | 4  | 5  | 5  | 6  | 7  |

如您所见,ID = 1->奇数,因此值必须按ASC

排序

这是到目前为止的代码:

declare 

type grades_array is table of grades%rowtype index by pls_integer;
grades_a grades_array;
cnt number;


begin 
Select count(id) into cnt from grades;
For i in 1..cnt loop
--I used an associative array 
Select * into grades_a(i) from grades where grades.id=i;
end loop;

For i in grades_a.FIRST..grades_a.LAST loop
if (mod(grades_a(i).id,2)=1)then .......
--I don't know how to sort the specific rows, in this case ASC
--dbms_output.put_line(grades_a(i).col1);
end if;
end loop;
--Also it is specified in the exercise that the table can change, e.g add more columns
end;

1 个答案:

答案 0 :(得分:0)

我只想使用PIVOT/UNPIVOT

首先对表进行UNPIVOT并按升序/降序为每个列值分配一个等级。

SQL Fiddle

查询1

SELECT id,
       colval,
       ROW_NUMBER () OVER (
          PARTITION BY id
          ORDER BY CASE MOD (id, 2) WHEN 1 THEN colval END,
                   CASE MOD (id, 2) WHEN 0 THEN colval END DESC) r
  FROM x UNPIVOT (colval FOR colname
         IN (col1 AS 'col1', col2 AS 'col2', col3 AS 'col3', col4 AS 'col4',
             col5 AS 'col5', col6 AS 'col6', col7 AS 'col7')
             )

<强> Results

| ID | COLVAL | R |
|----|--------|---|
|  1 |      3 | 1 |
|  1 |      4 | 2 |
|  1 |      4 | 3 |
|  1 |      6 | 4 |
|  1 |      7 | 5 |
|  1 |      8 | 6 |
|  1 |      8 | 7 |
|  2 |      9 | 1 |
|  2 |      8 | 2 |
|  2 |      7 | 3 |
|  2 |      7 | 4 |
|  2 |      5 | 5 |
|  2 |      2 | 6 |
|  2 |      1 | 7 |
|  3 |      1 | 1 |
|  3 |      2 | 2 |
|  3 |      4 | 3 |
|  3 |      5 | 4 |
|  3 |      7 | 5 |
|  3 |      8 | 6 |
|  3 |      9 | 7 |
|  4 |      9 | 1 |
|  4 |      8 | 2 |
|  4 |      7 | 3 |
|  4 |      4 | 4 |
|  4 |      4 | 5 |
|  4 |      4 | 6 |
|  4 |      1 | 7 |
|  5 |      2 | 1 |
|  5 |      2 | 2 |
|  5 |      4 | 3 |
|  5 |      5 | 4 |
|  5 |      5 | 5 |
|  5 |      6 | 6 |
|  5 |      7 | 7 |

然后根据等级PIVOT结果。

查询2

WITH pivoted AS (
SELECT id,
       colval,
       ROW_NUMBER () OVER (
          PARTITION BY id
          ORDER BY CASE MOD (id, 2) WHEN 1 THEN colval END,
                   CASE MOD (id, 2) WHEN 0 THEN colval END DESC) r
  FROM x UNPIVOT (colval FOR colname
         IN (col1 AS 'col1', col2 AS 'col2', col3 AS 'col3', col4 AS 'col4',
             col5 AS 'col5', col6 AS 'col6', col7 AS 'col7')
             )
)
SELECT * FROM pivoted
PIVOT (MAX (colval)
           FOR r
           IN (1 AS col1, 2 AS col2, 3 AS col3, 4 AS col4,
               5 AS col5, 6 AS col6, 7 AS col7))

<强> Results

| ID | COL1 | COL2 | COL3 | COL4 | COL5 | COL6 | COL7 |
|----|------|------|------|------|------|------|------|
|  1 |    3 |    4 |    4 |    6 |    7 |    8 |    8 |
|  2 |    9 |    8 |    7 |    7 |    5 |    2 |    1 |
|  3 |    1 |    2 |    4 |    5 |    7 |    8 |    9 |
|  4 |    9 |    8 |    7 |    4 |    4 |    4 |    1 |
|  5 |    2 |    2 |    4 |    5 |    5 |    6 |    7 |