从日期记录中获取日期作为列 Header

Get Day as Column Header from Date Records

我在tableEMP_DATES中有以下数据。

我想从 table 获得以下输出:

我该怎么做。我使用了以下 SQL 查询,但不确定如何将日作为列 header.

SELECT TO_CHAR (start_date, 'Day'),
       TO_CHAR (completion_date, 'Day'),
       start_date,
       completion_date,
       ROUND ( (completion_date - start_date) * 24, 1)
  FROM emp_dates

Table:

CREATE TABLE EMP_DATES
(
   START_DATE        DATE,
   COMPLETION_DATE   DATE
);


SET DEFINE OFF;

INSERT INTO EMP_DATES (START_DATE, COMPLETION_DATE)
     VALUES (
               TO_DATE ('02/29/2016 12:24:25', 'MM/DD/YYYY HH24:MI:SS'),
               TO_DATE ('02/29/2016 15:30:00', 'MM/DD/YYYY HH24:MI:SS'));

INSERT INTO EMP_DATES (START_DATE, COMPLETION_DATE)
     VALUES (
               TO_DATE ('03/01/2016 07:00:00', 'MM/DD/YYYY HH24:MI:SS'),
               TO_DATE ('03/01/2016 11:54:25', 'MM/DD/YYYY HH24:MI:SS'));

COMMIT;

您正在尝试将行转换为列,但由于您使用的是 10g,实际的 PIVOT 子句不可用;所以你需要用案例语句和聚合的扩展方式来做到这一点:

SELECT
  SUM(CASE WHEN TO_CHAR (start_date, 'FMDay') = 'Sunday' THEN
    ROUND ( (completion_date - start_date) * 24, 1) END) AS "Sunday",
  SUM(CASE WHEN TO_CHAR (start_date, 'FMDay') = 'Monday' THEN
    ROUND ( (completion_date - start_date) * 24, 1) END) AS "Monday",
  SUM(CASE WHEN TO_CHAR (start_date, 'FMDay') = 'Tuesday' THEN
    ROUND ( (completion_date - start_date) * 24, 1) END) AS "Tuesday",
  SUM(CASE WHEN TO_CHAR (start_date, 'FMDay') = 'Wednesday' THEN
    ROUND ( (completion_date - start_date) * 24, 1) END) AS "Wednesday",
  SUM(CASE WHEN TO_CHAR (start_date, 'FMDay') = 'Thursday' THEN
    ROUND ( (completion_date - start_date) * 24, 1) END) AS "Thursday",
  SUM(CASE WHEN TO_CHAR (start_date, 'FMDay') = 'Friday' THEN
    ROUND ( (completion_date - start_date) * 24, 1) END) AS "Friday",
  SUM(CASE WHEN TO_CHAR (start_date, 'FMDay') = 'Saturday' THEN
    ROUND ( (completion_date - start_date) * 24, 1) END) AS "Saturday"
FROM emp_dates;

    Sunday     Monday    Tuesday  Wednesday   Thursday     Friday   Saturday
---------- ---------- ---------- ---------- ---------- ---------- ----------
                  3.1        4.9                                            

'FM' format modifier 停止由 to_char() 生成的值被空格填充,这是默认情况下 'Day' 和 'Dy' 发生的情况;否则,还需要填充文本文字,例如'Monday '.

您可以使用子查询稍微简化一下代码:

SELECT
  SUM(CASE WHEN dy = 'Sun' THEN hours END) AS "Sunday",
  SUM(CASE WHEN dy = 'Mon' THEN hours END) AS "Monday",
  SUM(CASE WHEN dy = 'Tue' THEN hours END) AS "Tuesday",
  SUM(CASE WHEN dy = 'Wed' THEN hours END) AS "Wednesday",
  SUM(CASE WHEN dy = 'Thu' THEN hours END) AS "Thursday",
  SUM(CASE WHEN dy = 'Fri' THEN hours END) AS "Friday",
  SUM(CASE WHEN dy = 'Sat' THEN hours END) AS "Saturday"
FROM (
  SELECT TO_CHAR (start_date, 'FMDy', 'NLS_DATE_LANGUAGE=English') AS dy,
    ROUND ( (completion_date - start_date) * 24, 1) AS hours
  FROM emp_dates
);

    Sunday     Monday    Tuesday  Wednesday   Thursday     Friday   Saturday
---------- ---------- ---------- ---------- ---------- ---------- ----------
                  3.1        4.9                                            

我还更改了使用缩写的日期名称只是因为它更短,并指定了为此使用的语言 - 以防客户端会话 运行 这不是英语,这将使与字符串文字的比较失败。 (您可以阅读更多相关内容 in the documentation)。

在第一个版本中,例如,如果会话语言是法语,to_char() 将得到 'Lundi',这与固定值 'Monday' 不匹配。您也可以使用天数进行比较,但这也会受到 NLS 设置的影响,并且不能像语言那样更改。