反透视 Oracle 中的多列 SQL
Unpivot Multiple Columns in Oracle SQL
我需要逆轴旋转 table,类似于下面的 table:
create TABLE dummy_x
(
EMP_NAME VARCHAR2(100)
, EMP_NUMBER VARCHAR2(100)
, PAYROLL_NAME VARCHAR2(100)
, PAYROLL_ID NUMBER
, JOB_TITLE VARCHAR2(100)
, JOB_TITLE_ID NUMBER
, LOCATION VARCHAR2(100)
, LOCATION_ID NUMBER
, NEW_PAYROLL_NAME VARCHAR2(100)
, NEW_PAYROLL_ID NUMBER
, NEW_JOB_TITLE VARCHAR2(100)
, NEW_JOB_TITLE_ID NUMBER
, NEW_LOCATION VARCHAR2(100)
, NEW_LOCATION_ID NUMBER
);
INSERT INTO dummy_x (EMP_NAME, EMP_NUMBER, PAYROLL_NAME, PAYROLL_ID, JOB_TITLE, JOB_TITLE_ID, LOCATION, LOCATION_ID, NEW_PAYROLL_NAME, NEW_PAYROLL_ID, NEW_JOB_TITLE, NEW_JOB_TITLE_ID, NEW_LOCATION, NEW_LOCATION_ID)
VALUES ('MISIP', '111X', 'PAY1', 1, 'DEVELOPER', 2, 'PHIL', 3, 'PAYPHIL', 11, 'PHIL DEV', 22, 'MANILA PH', 33);
INSERT INTO dummy_x (EMP_NAME, EMP_NUMBER, PAYROLL_NAME, PAYROLL_ID, JOB_TITLE, JOB_TITLE_ID, LOCATION, LOCATION_ID, NEW_PAYROLL_NAME, NEW_PAYROLL_ID, NEW_JOB_TITLE, NEW_JOB_TITLE_ID, NEW_LOCATION, NEW_LOCATION_ID)
VALUES ('FHONS', '111Y', 'PAY2', 2, 'SUPPORT', 3, 'HONDURAS', 4, 'PAYHON', 55, 'HON SUP', 66, 'SP SULA HON', 77);
我需要如下格式:
EMP_NAME EMP_NUMBER DETAILS CURRENT_VALUE NEW_VALUE
--------- ------------ -------------- -------------- ----------
MISIP 111X PAYROLL_NAME PAY1 PAYPHIL
PAYROLL_ID 1 11
JOB_TITLE DEVELOPER PHIL DEV
JOB_TITLE_ID 2 22
LOCATION PHIL MANILA PH
LOCATION_ID 3 33
FHONS 111Y PAYROLL_NAME PAY2 PAYHON
PAYROLL_ID 2 55
JOB_TITLE SUPPORT HON SUP
JOB_TITLE_ID 3 66
LOCATION HONDURAS SP SULA HON
LOCATION_ID 4 77
这是我到目前为止所做的:
SELECT EMP_NAME
, EMP_NUMBER
, Details
, current_value
FROM (SELECT EMP_NAME
, EMP_NUMBER
, PAYROLL_NAME
, cast(PAYROLL_ID as varchar2(100)) PAYROLL_ID
, JOB_TITLE
, cast(JOB_TITLE_ID as varchar2(100)) JOB_TITLE_ID
, LOCATION
, cast(LOCATION_ID as varchar2(100)) LOCATION_ID
, NEW_PAYROLL_NAME
, cast(NEW_PAYROLL_ID as varchar2(100)) NEW_PAYROLL_ID
, NEW_JOB_TITLE
, cast(NEW_JOB_TITLE_ID as varchar2(100)) NEW_JOB_TITLE_ID
, NEW_LOCATION
, cast(NEW_LOCATION_ID as varchar2(100)) NEW_LOCATION_ID
FROM dummy_x)
unpivot (current_value for Details in (PAYROLL_NAME
, PAYROLL_ID
, JOB_TITLE
, JOB_TITLE_ID
, LOCATION
, LOCATION_ID));
查询输出
EMP_NAME EMP_NUMBER DETAILS CURRENT_VALUE NEW_VALUE
--------- ------------ -------------- -------------- ----------
MISIP 111X PAYROLL_NAME PAY1
MISIP 111X PAYROLL_ID 1
MISIP 111X JOB_TITLE DEVELOPER
MISIP 111X JOB_TITLE_ID 2
MISIP 111X LOCATION PHIL
MISIP 111X LOCATION_ID 3
FHONS 111Y PAYROLL_NAME PAY2
FHONS 111Y PAYROLL_ID 2
FHONS 111Y JOB_TITLE SUPPORT
FHONS 111Y JOB_TITLE_ID 3
FHONS 111Y LOCATION HONDURAS
FHONS 111Y LOCATION_ID 4
如何将 "New Value" 列数据添加到此脚本,是否可以从 EMP_NAME 和 EMP_NUMBER 列中删除重复数据?
要获得两列比您想象的要容易得多:unpivot ( (current_value, new_value) for details in...)
当然,"details" 也应该成对给出,每个包含在 ( ... , ... )
中。例如:for ((payroll_name, new_payroll_name) as 'PAYROLL NAME', .... )
第二个要求没有意义。哪一行应该保留 EMP_NAME 和 EMP_NUMBER,哪一行应该显示 NULL?如果您 "think" 应该获取值的行实际上不存在,或者必须在进一步处理中删除怎么办?这是你应该在前端应用程序中做的事情(例如在 SQL*Plus 中,你想做的事情很容易做到)。
在您的应用程序代码中合并单元格。
对于 new_value,试试这个:
SELECT EMP_NAME
, EMP_NUMBER
, Details
, current_value
, new_value
FROM (SELECT EMP_NAME
, EMP_NUMBER
, PAYROLL_NAME
, cast(PAYROLL_ID as varchar2(100)) PAYROLL_ID
, JOB_TITLE
, cast(JOB_TITLE_ID as varchar2(100)) JOB_TITLE_ID
, LOCATION
, cast(LOCATION_ID as varchar2(100)) LOCATION_ID
, NEW_PAYROLL_NAME
, cast(NEW_PAYROLL_ID as varchar2(100)) NEW_PAYROLL_ID
, NEW_JOB_TITLE
, cast(NEW_JOB_TITLE_ID as varchar2(100)) NEW_JOB_TITLE_ID
, NEW_LOCATION
, cast(NEW_LOCATION_ID as varchar2(100)) NEW_LOCATION_ID
FROM dummy_x)
unpivot ((current_value, new_value) for Details in (
(PAYROLL_NAME, NEW_PAYROLL_NAME) as 'PAYROLL_NAME'
, (PAYROLL_ID , NEW_PAYROLL_ID ) as 'PAYROLL_ID'
, (JOB_TITLE , NEW_JOB_TITLE ) as 'JOB_TITLE'
, (JOB_TITLE_ID, NEW_JOB_TITLE_ID) as 'JOB_TITLE_ID'
, (LOCATION , NEW_LOCATION ) as 'LOCATION'
, (LOCATION_ID , NEW_LOCATION_ID) as 'LOCATION_ID'
)
);
我需要逆轴旋转 table,类似于下面的 table:
create TABLE dummy_x
(
EMP_NAME VARCHAR2(100)
, EMP_NUMBER VARCHAR2(100)
, PAYROLL_NAME VARCHAR2(100)
, PAYROLL_ID NUMBER
, JOB_TITLE VARCHAR2(100)
, JOB_TITLE_ID NUMBER
, LOCATION VARCHAR2(100)
, LOCATION_ID NUMBER
, NEW_PAYROLL_NAME VARCHAR2(100)
, NEW_PAYROLL_ID NUMBER
, NEW_JOB_TITLE VARCHAR2(100)
, NEW_JOB_TITLE_ID NUMBER
, NEW_LOCATION VARCHAR2(100)
, NEW_LOCATION_ID NUMBER
);
INSERT INTO dummy_x (EMP_NAME, EMP_NUMBER, PAYROLL_NAME, PAYROLL_ID, JOB_TITLE, JOB_TITLE_ID, LOCATION, LOCATION_ID, NEW_PAYROLL_NAME, NEW_PAYROLL_ID, NEW_JOB_TITLE, NEW_JOB_TITLE_ID, NEW_LOCATION, NEW_LOCATION_ID)
VALUES ('MISIP', '111X', 'PAY1', 1, 'DEVELOPER', 2, 'PHIL', 3, 'PAYPHIL', 11, 'PHIL DEV', 22, 'MANILA PH', 33);
INSERT INTO dummy_x (EMP_NAME, EMP_NUMBER, PAYROLL_NAME, PAYROLL_ID, JOB_TITLE, JOB_TITLE_ID, LOCATION, LOCATION_ID, NEW_PAYROLL_NAME, NEW_PAYROLL_ID, NEW_JOB_TITLE, NEW_JOB_TITLE_ID, NEW_LOCATION, NEW_LOCATION_ID)
VALUES ('FHONS', '111Y', 'PAY2', 2, 'SUPPORT', 3, 'HONDURAS', 4, 'PAYHON', 55, 'HON SUP', 66, 'SP SULA HON', 77);
我需要如下格式:
EMP_NAME EMP_NUMBER DETAILS CURRENT_VALUE NEW_VALUE
--------- ------------ -------------- -------------- ----------
MISIP 111X PAYROLL_NAME PAY1 PAYPHIL
PAYROLL_ID 1 11
JOB_TITLE DEVELOPER PHIL DEV
JOB_TITLE_ID 2 22
LOCATION PHIL MANILA PH
LOCATION_ID 3 33
FHONS 111Y PAYROLL_NAME PAY2 PAYHON
PAYROLL_ID 2 55
JOB_TITLE SUPPORT HON SUP
JOB_TITLE_ID 3 66
LOCATION HONDURAS SP SULA HON
LOCATION_ID 4 77
这是我到目前为止所做的:
SELECT EMP_NAME
, EMP_NUMBER
, Details
, current_value
FROM (SELECT EMP_NAME
, EMP_NUMBER
, PAYROLL_NAME
, cast(PAYROLL_ID as varchar2(100)) PAYROLL_ID
, JOB_TITLE
, cast(JOB_TITLE_ID as varchar2(100)) JOB_TITLE_ID
, LOCATION
, cast(LOCATION_ID as varchar2(100)) LOCATION_ID
, NEW_PAYROLL_NAME
, cast(NEW_PAYROLL_ID as varchar2(100)) NEW_PAYROLL_ID
, NEW_JOB_TITLE
, cast(NEW_JOB_TITLE_ID as varchar2(100)) NEW_JOB_TITLE_ID
, NEW_LOCATION
, cast(NEW_LOCATION_ID as varchar2(100)) NEW_LOCATION_ID
FROM dummy_x)
unpivot (current_value for Details in (PAYROLL_NAME
, PAYROLL_ID
, JOB_TITLE
, JOB_TITLE_ID
, LOCATION
, LOCATION_ID));
查询输出
EMP_NAME EMP_NUMBER DETAILS CURRENT_VALUE NEW_VALUE
--------- ------------ -------------- -------------- ----------
MISIP 111X PAYROLL_NAME PAY1
MISIP 111X PAYROLL_ID 1
MISIP 111X JOB_TITLE DEVELOPER
MISIP 111X JOB_TITLE_ID 2
MISIP 111X LOCATION PHIL
MISIP 111X LOCATION_ID 3
FHONS 111Y PAYROLL_NAME PAY2
FHONS 111Y PAYROLL_ID 2
FHONS 111Y JOB_TITLE SUPPORT
FHONS 111Y JOB_TITLE_ID 3
FHONS 111Y LOCATION HONDURAS
FHONS 111Y LOCATION_ID 4
如何将 "New Value" 列数据添加到此脚本,是否可以从 EMP_NAME 和 EMP_NUMBER 列中删除重复数据?
要获得两列比您想象的要容易得多:unpivot ( (current_value, new_value) for details in...)
当然,"details" 也应该成对给出,每个包含在 ( ... , ... )
中。例如:for ((payroll_name, new_payroll_name) as 'PAYROLL NAME', .... )
第二个要求没有意义。哪一行应该保留 EMP_NAME 和 EMP_NUMBER,哪一行应该显示 NULL?如果您 "think" 应该获取值的行实际上不存在,或者必须在进一步处理中删除怎么办?这是你应该在前端应用程序中做的事情(例如在 SQL*Plus 中,你想做的事情很容易做到)。
在您的应用程序代码中合并单元格。
对于 new_value,试试这个:
SELECT EMP_NAME
, EMP_NUMBER
, Details
, current_value
, new_value
FROM (SELECT EMP_NAME
, EMP_NUMBER
, PAYROLL_NAME
, cast(PAYROLL_ID as varchar2(100)) PAYROLL_ID
, JOB_TITLE
, cast(JOB_TITLE_ID as varchar2(100)) JOB_TITLE_ID
, LOCATION
, cast(LOCATION_ID as varchar2(100)) LOCATION_ID
, NEW_PAYROLL_NAME
, cast(NEW_PAYROLL_ID as varchar2(100)) NEW_PAYROLL_ID
, NEW_JOB_TITLE
, cast(NEW_JOB_TITLE_ID as varchar2(100)) NEW_JOB_TITLE_ID
, NEW_LOCATION
, cast(NEW_LOCATION_ID as varchar2(100)) NEW_LOCATION_ID
FROM dummy_x)
unpivot ((current_value, new_value) for Details in (
(PAYROLL_NAME, NEW_PAYROLL_NAME) as 'PAYROLL_NAME'
, (PAYROLL_ID , NEW_PAYROLL_ID ) as 'PAYROLL_ID'
, (JOB_TITLE , NEW_JOB_TITLE ) as 'JOB_TITLE'
, (JOB_TITLE_ID, NEW_JOB_TITLE_ID) as 'JOB_TITLE_ID'
, (LOCATION , NEW_LOCATION ) as 'LOCATION'
, (LOCATION_ID , NEW_LOCATION_ID) as 'LOCATION_ID'
)
);