|
2011-11-5答案BC. 注意B这种写法比较不常见。
===============================
2011-11-12 列转行
作者:Kim Berg Hansen
难度:高
我创建了如下的表并填入数据:
CREATE TABLE plch_employees
(
employee_id INTEGER
, last_name VARCHAR2 (20)
, hire_date DATE
, promote_date DATE
, fire_date DATE
)
/
INSERT INTO plch_employees
VALUES (
100,
'Jobs',
DATE '1995-01-01',
DATE '2005-01-01',
DATE '2010-01-01'
)
/
INSERT INTO plch_employees
VALUES (
200,
'Ellison',
DATE '1990-01-01',
DATE '2000-01-01',
NULL
)
/
INSERT INTO plch_employees
VALUES (
300,
'Gates',
DATE '2001-01-01',
NULL,
DATE '2002-01-01'
)
/
COMMIT
/
我老板想要一张 HR 部门的录用、提升、解雇时间的时间表。换句话说,他想要一个清单,包含了事件日期、事件(录用、提升或解雇)和员工的姓。
哪些选项能够产生这样一个清单(如下所示)包含了上述的七个HR事件?
EVENT_DATE EVENT LAST_NAME
------------- ---------- ------------------------------
01-JAN-90 Hire Ellison
01-JAN-95 Hire Jobs
01-JAN-00 Promote Ellison
01-JAN-01 Hire Gates
01-JAN-02 Fire Gates
01-JAN-05 Promote Jobs
01-JAN-10 Fire Jobs
(A)
SELECT event_date
, event
, last_name
FROM plch_employees
UNPIVOT INCLUDE NULLS (
event_date FOR event IN (
hire_date AS 'Hire',
promote_date AS 'Promote',
fire_date AS 'Fire'
)
)
ORDER BY event_date;
(B)
SELECT CASE d.dummy
WHEN 1 THEN e.hire_date
WHEN 2 THEN e.promote_date
WHEN 3 THEN e.fire_date
END event_date,
CASE d.dummy
WHEN 1 THEN 'Hire'
WHEN 2 THEN 'Promote'
WHEN 3 THEN 'Fire'
END event,
e.last_name
FROM plch_employees e
CROSS JOIN (
SELECT LEVEL AS dummy
FROM DUAL
CONNECT BY LEVEL <= 3
) d
ORDER BY event_date;
(C)
SELECT event_date
, event
, last_name
FROM plch_employees
PIVOT (
MAX(event_date)
FOR event IN (
hire_date AS 'Hire',
promote_date AS 'Promote',
fire_date AS 'Fire'
)
)
ORDER BY event_date;
(D)
SELECT event_date
, event
, last_name
FROM plch_employees
UNPIVOT (
event_date FOR event IN (
hire_date AS 'Hire',
promote_date AS 'Promote',
fire_date AS 'Fire'
)
)
ORDER BY event_date;
(E)
WITH events AS (
SELECT 'Hire' event FROM DUAL
UNION ALL
SELECT 'Promote' event FROM DUAL
UNION ALL
SELECT 'Fire' event FROM DUAL
)
SELECT event_date
, event
, last_name
FROM (
SELECT CASE events.event
WHEN 'Hire' THEN e.hire_date
WHEN 'Promote' THEN e.promote_date
WHEN 'Fire' THEN e.fire_date
END event_date,
events.event,
e.last_name
FROM plch_employees e
CROSS JOIN events
) evt
WHERE event_date IS NOT NULL
ORDER BY event_date;
(F)
, event
, last_name
FROM (
SELECT CASE d.dummy
WHEN 1 THEN e.hire_date
WHEN 2 THEN e.promote_date
WHEN 3 THEN e.fire_date
END event_date,
CASE d.dummy
WHEN 1 THEN 'Hire'
WHEN 2 THEN 'Promote'
WHEN 3 THEN 'Fire'
END event,
e.last_name
FROM plch_employees e
CROSS JOIN (
SELECT LEVEL AS dummy
FROM DUAL
CONNECT BY LEVEL <= 3
) d
) evt
WHERE event_date IS NOT NULL
ORDER BY event_date;
|
|