Oracle sql查询创建聚合视图

时间:2013-02-24 08:01:55

标签: sql oracle aggregate-functions

将公司日历存储在数据库中,如下所示。请注意,公司日历从周六到周五开始: -

   Date1      Week     Month   Quarter     Year    Shift
23-FEB-13   9       6        2         2013     ABC
23-FEB-13   9       6        2         2013     DEF
22-FEB-13   9       6        2         2013     ABC1
22-FEB-13   9       6        2         2013     DEF2
21-FEB-13   8       6        2         2013     DEF2

我要做的是创建一个视图来存储Week#,StartWeek,EndWeek,即存储当前周的开始和结束日期,如

Week   StartWeek    EndWeek

  9        22-FEB-13     23-FEB-13

这是我到目前为止所拥有的

SELECT START_DATETIME, F_WEEK, ROW_NUMBER( ) OVER (PARTITION BY F_WEEK, F_YEAR ORDER BY SHIFT DESC) RNUM FROM COMMON.FISCAL_CALENDAR  WHERE F_WEEK IN (SELECT F_WEEK FROM COMMON.FISCAL_CALENDAR WHERE TO_DATE(START_DATETIME, 'DD-MON-YY') = TO_DATE(SYSDATE, 'DD-MON-YY')) AND F_YEAR IN (SELECT F_YEAR FROM COMMON.FISCAL_CALENDAR WHERE TO_DATE(START_DATETIME, 'DD-MON-YY') = TO_DATE(SYSDATE, 'DD-MON-YY')) ORDER BY START_DATETIME DESC

如果有人能更多地了解这一点会非常感激吗?

3 个答案:

答案 0 :(得分:2)

包含周开始/结束日期和周数的周表 - 您可以使用开始日期和结束日期的日期并添加计算:

SELECT start_date 
     , TRUNC(start_date, 'iw')                  wk_starts  
     , TRUNC(start_date, 'iw') + 7 - 1/86400    wk_ends
     , TO_NUMBER (TO_CHAR (start_date, 'IW'))   ISO_wk#  
 FROM
 (
  SELECT TRUNC(SYSDATE, 'YEAR')-1 + LEVEL AS start_date
    FROM dual
  CONNECT BY LEVEL <= 
  (
  SELECT TRUNC(ADD_MONTHS (SYSDATE, 12), 'Y')-TRUNC(SYSDATE, 'Y') "Num of Days in 2013"   
   FROM dual
  )
 )
/

START_DATE    WK_STARTS    WK_ENDS               ISO_WK#
----------------------------------------------------
1/1/2013    12/31/2012    1/6/2013 11:59:59 PM    1
1/2/2013    12/31/2012    1/6/2013 11:59:59 PM    1
 ....
....
1/7/2013    1/7/2013    1/13/2013 11:59:59 PM    2
1/8/2013    1/7/2013    1/13/2013 11:59:59 PM    2

这些是快速修复建议。您可以添加更多计算,因为您知道表和日期... 对于公司日历,您需要在上面的查询中添加一些计算和更改。 您可以添加结束日期。我建立了年度表,但您可以将CONNECT BY中的日期替换为您的日期,例如您的日期之间的天数

...CONNECT BY LEVEL <= (your_end_date - your_start_date) 

其他修正:

  1. 将FROM子句中的start_date替换为开始日期 - 这将是此更改后的第一个SAT。您可以选择任何其他SAT作为开始日期,不必是年度最佳SAT:

       SELECT Next_Day(Trunc(Sysdate,'Y'),'SAT') + LEVEL-1 AS start_date FROM dual...
    
  2. 在ISO_Wk#之后将CASE添加到外部查询。删除不需要的列......:

    SELECT start_date 
     , TRUNC(start_date, 'iw')                  wk_starts  
     , TRUNC(start_date, 'iw') + 7 - 1/86400    wk_ends
     , TO_NUMBER (TO_CHAR (start_date, 'IW'))   ISO_wk# 
     , (CASE WHEN TO_CHAR(start_date, 'DY') = 'SAT' THEN start_date END) your_wk_start
     , (CASE WHEN TO_CHAR(start_date, 'DY') = 'FRI' THEN TRUNC(start_date, 'iw') + 7 - 1/86400 END) your_wk_end
      ....
    START_DATE    WK_STARTS    WK_ENDS    ISO_WK#    WK_DAY    YOUR_WK_START    YOUR_WK_END
    --------------------------------------------------------------------------------------
    1/5/2013    12/31/2012    1/6/2013 11:59:59 PM    1    SAT    1/5/2013    
    1/6/2013    12/31/2012    1/6/2013 11:59:59 PM    1    SUN        
    ....
    ....
    1/11/2013    1/7/2013    1/13/2013 11:59:59 PM    2    FRI                1/13/2013 11:59:59 PM
    1/12/2013    1/7/2013    1/13/2013 11:59:59 PM    2    SAT    1/12/2013    
    ....
    ....       
    1/18/2013    1/14/2013    1/20/2013 11:59:59 PM    3    FRI               1/20/2013 11:59:59 PM
    

答案 1 :(得分:1)

我认为您的需求是关于按星期分组的最小和最大日期:

SELECT Week, MIN(Date) As StartWeek, MAX(Date) As EndWeek  
FROM original_table
GROUP BY Week;

如果您只对本周感兴趣:

SELECT Week, MIN(Date) As StartWeek, MAX(Date) As EndWeek  
FROM original_table
WHERE Week = TO_CHAR(sysdate, 'IW');

答案 2 :(得分:0)

这是

SELECT MAX(DATE1) AS SHIFT_END_TIME, MIN(DATE1) AS SHIFT_START_TIME, WEEK, YEAR FROM MYTABLE GROUP BY WEEK, YEAR HAVING WEEK IN (SELECT WEEK FROM MYTABLE  WHERE TO_DATE(DATE1,   'DD-MON-YY') = TO_DATE(SYSDATE, 'DD-MON-YY')) AND YEAR IN (SELECT YEAR FROM MYTABLE WHERE TO_DATE(DATE1, 'DD- MON-YY') = TO_DATE(SYSDATE, 'DD-MON-YY'))