使用oracle将值作为具有相应值的行

时间:2016-01-05 04:39:23

标签: sql oracle multiple-columns rows

我的表格数据如下

DEPTNO ENAME       SALARY
------ ----------  ------
Developer SENIOR       100000
Developer JUNIOR       100000
Tester    SENIOR       200000
Tester    JUNIOR       100000
Architect SENIOR       300000
Architect JUNIOR       300000

我需要像

一样展示它们
Occupation Senior Sal  Junior Sal
------ ----------      ------
Developer SENIOR       JUNIOR
Developer 100000       100000
Tester    SENIOR       JUNIOR
Tester    200000       100000
Architect SENIOR       JUNIOR
Architect 300000       300000

坚持这个如何实现这个

2 个答案:

答案 0 :(得分:3)

使用

  • 解码
  • ROW_NUMBER
  • UNION ALL
SELECT deptno,
  senior_sal,
  junior_sal,
  row_number() over(partition BY deptno order by senior_sal DESC) rn
FROM
  (SELECT A.deptno, A.salary senior_sal, b.salary junior_sal
  FROM
    (SELECT deptno, TO_CHAR(salary) salary FROM your_table WHERE ename = 'SENIOR'
    ) A,
    (SELECT deptno, TO_CHAR(salary) salary FROM your_table WHERE ename = 'JUNIOR'
    ) b
  WHERE A.deptno = b.deptno
  UNION ALL
  SELECT A.deptno, A.salary senior_sal, b.salary junior_sal
  FROM
    (SELECT deptno, DECODE(ename, 'SENIOR', 'SENIOR') salary FROM your_table
    WHERE ename = 'SENIOR'
    ) A,
    (SELECT deptno, DECODE(ename, 'JUNIOR', 'JUNIOR') salary FROM your_table
    WHERE ename = 'JUNIOR'
    ) b
  WHERE A.deptno = b.deptno
  );

工作演示

在SQL * Plus中:

SQL> column rn noprint
SQL> WITH sample_data AS(
  2  SELECT 'Developer' DEPTNO, 'SENIOR' ENAME, 100000 SALARY FROM dual UNION ALL
  3  SELECT 'Developer' DEPTNO, 'JUNIOR' ENAME, 100000 SALARY FROM dual UNION ALL
  4  SELECT 'Tester' DEPTNO,    'SENIOR' ENAME, 200000 SALARY FROM dual UNION ALL
  5  SELECT 'Tester' DEPTNO,    'JUNIOR' ENAME, 100000 SALARY FROM dual UNION ALL
  6  SELECT 'Architect' DEPTNO, 'SENIOR' ENAME, 300000 SALARY FROM dual UNION ALL
  7  SELECT 'Architect' DEPTNO, 'JUNIOR' ENAME, 300000 SALARY FROM dual
  8  )
  9  -- end of sample_data mimicking real table
 10  SELECT deptno,
 11    senior_sal,
 12    junior_sal,
 13    row_number() over(partition BY deptno order by senior_sal DESC) rn
 14  FROM
 15    (SELECT A.deptno, A.salary senior_sal, b.salary junior_sal
 16    FROM
 17      (SELECT deptno, TO_CHAR(salary) salary FROM sample_data WHERE ename = 'SENIOR'
 18      ) A,
 19      (SELECT deptno, TO_CHAR(salary) salary FROM sample_data WHERE ename = 'JUNIOR'
 20      ) b
 21    WHERE A.deptno = b.deptno
 22    UNION ALL
 23    SELECT A.deptno, A.salary senior_sal, b.salary junior_sal
 24    FROM
 25      (SELECT deptno, DECODE(ename, 'SENIOR', 'SENIOR') salary FROM sample_data
 26      WHERE ename = 'SENIOR'
 27      ) A,
 28      (SELECT deptno, DECODE(ename, 'JUNIOR', 'JUNIOR') salary FROM sample_data
 29      WHERE ename = 'JUNIOR'
 30      ) b
 31    WHERE A.deptno = b.deptno
 32    );

<强>输出

DEPTNO          SENIOR_SAL      JUNIOR_SAL
--------------- --------------- ---------------
Architect       SENIOR          JUNIOR
Architect       300000          300000
Developer       SENIOR          JUNIOR
Developer       100000          100000
Tester          SENIOR          JUNIOR
Tester          200000          100000

6 rows selected.

SQL>

答案 1 :(得分:0)

您可以使用 LISTAGG

WITH sample_data AS(
    SELECT 'Developer' DEPTNO, 'SENIOR' ENAME, 100000 SALARY FROM dual UNION ALL
    SELECT 'Developer' DEPTNO, 'JUNIOR' ENAME, 100000 SALARY FROM dual UNION ALL
    SELECT 'Tester' DEPTNO,    'SENIOR' ENAME, 200000 SALARY FROM dual UNION ALL
    SELECT 'Tester' DEPTNO,    'JUNIOR' ENAME, 100000 SALARY FROM dual UNION ALL
    SELECT 'Architect' DEPTNO, 'SENIOR' ENAME, 300000 SALARY FROM dual UNION ALL
    SELECT 'Architect' DEPTNO, 'JUNIOR' ENAME, 300000 SALARY FROM dual
)
SELECT occupation, SUBSTR(name_sal,1,INSTR(name_sal,',')-1) "Senior Sal", SUBSTR(name_sal,INSTR(name_sal,',')+1) "Junior Sal"
FROM
(
    SELECT DEPTNO as occupation,LISTAGG (ename, ',') WITHIN GROUP (ORDER BY ename DESC)  name_sal
    FROM sample_data
    GROUP BY DEPTNO
    UNION
    SELECT deptno as occupation,LISTAGG (salary, ',') WITHIN GROUP (ORDER BY ename DESC)  
    FROM sample_data
    GROUP BY deptno
)
ORDER BY 1, 2 DESC