【问题标题】:Get Day as Column Header from Date Records从日期记录中获取日期作为列标题
【发布时间】:2016-03-24 12:34:23
【问题描述】:

我在表EMP_DATES中有以下数据。

我想从表格中实现以下输出:

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

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

表:

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;

【问题讨论】:

    标签: sql oracle11g oracle10g


    【解决方案1】:

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

    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 设置的影响,并且无法像语言那样更改。

    【讨论】:

    • 谢谢亚历克斯,这太棒了,我会试试你的方法。
    • Alex,您能提供如何使用 PIVOT 函数获取输出吗?
    猜你喜欢
    • 2016-03-30
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多