似乎无法转换为有效的选择语句

时间:2013-02-23 20:16:12

标签: sql database oracle

我试图解决以下问题:

显示本周(例如,1-52),该周的开始和结束日期,以及2011年12月1日至2012年1月31日期间报告的传感器温度数,按周降序排序。

使用以下选择。

SELECT TO_CHAR(R.Report_Time,'WW') as Week, NEXT_DAY(R.Report_Time-7,'Monday'), NEXT_DAY(R.Report_Time-1, 'Sunday')
FROM REPORT R
WHERE R.Report_Time BETWEEN '01-DEC-2011' AND '31-JAN-2012'
GROUP BY Week
ORDER BY TO_CHAR(R.Report_Time, 'WW') DESC;

这会产生一些错误,不会让查询正确执行,例如不能按表达式进行分组。

表REPORT是一个报告列表,其中包含数据和报告时间。

修改

WE NEXT_DAY( NEXT_DAY( SENSOR_COUNT
-- --------- --------- ------------
03 16-JAN-12 22-JAN-12        1
02 09-JAN-12 15-JAN-12        1
02 09-JAN-12 15-JAN-12        1
02 09-JAN-12 15-JAN-12        1

打印出来的是什么。它似乎只是按周分组,正如你在这里看到的那样,我相信输出应该看得更接近:

WE NEXT_DAY( NEXT_DAY( SENSOR_COUNT
-- --------- --------- ------------
03 16-JAN-12 22-JAN-12        1
02 09-JAN-12 15-JAN-12        3

2 个答案:

答案 0 :(得分:1)

您不能使用GROUP BY别名。您必须完全指定要分组的表达式:

我还添加了一些可能会在未来发展的事情:

SELECT TO_CHAR(R.Report_Time,'WW') as Week
     , NEXT_DAY(R.Report_Time-7,'Monday')
     , NEXT_DAY(R.Report_Time-1, 'Sunday')
     , COUNT(*) Sensor_count
FROM REPORT R
WHERE R.Report_Time BETWEEN '01-DEC-2011' AND '31-JAN-2012'
GROUP BY TO_CHAR(R.Report_Time,'WW'), NEXT_DAY(R.Report_Time-7,'Monday')
       , NEXT_DAY(R.Report_Time-1, 'Sunday')
ORDER BY TO_CHAR(R.Report_Time, 'WW') DESC;

您的查询还有其他问题,因为您很快就会发现:-)您可能希望在此处使用分析函数。您还可以通过其他两列进行分组。

修改

根据你的编辑,我认为这会让你更接近:

SELECT week, first_day, last_day, COUNT(*)
  FROM (SELECT TO_CHAR(R.Report_Time,'WW') as Week
             , NEXT_DAY(R.Report_Time-7,'Monday') first_day
             , NEXT_DAY(R.Report_Time-1, 'Sunday') last_day
         FROM REPORT R
        WHERE R.Report_Time BETWEEN '01-DEC-2011' AND '31-JAN-2012')
 GROUP BY week, first_day, last_day
 ORDER BY week DESC;

答案 1 :(得分:0)

另外......使用ISO周的年度周表的例子。如果需要,将IW更改为WW。使用您的日期作为开始/结束日期和我的格式,以获得周日硬编码为'DY'的周日/结束日期。如果使用表日期和BETWEEN运算符,则不必使用CONNECT BY。我的例子不是基于表格。删除不必要的列,添加计数,按ISO_wk#(或非iso)分组,wk_starts,wk_ends ......:

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')+((LEVEL-1)*7)-1 AS start_date
    FROM dual
   CONNECT BY LEVEL <= 
   ( -- Nbr of days / 7 = 52 weeks in 2013 --
    SELECT Round((TRUNC(ADD_MONTHS (SYSDATE, 12), 'Y')-TRUNC(SYSDATE, 'Y'))/7) 
      FROM dual
   )
 )
/

START_DATE    WK_STARTS     WK_ENDS                ISO_WK#
-----------------------------------------------------------
12/31/2012    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/14/2013     1/14/2013     1/20/2013 11:59:59 PM     3
...
...
12/23/2013    12/23/2013    12/29/2013 11:59:59 PM    52

周号日历确认周日期和号码:http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php

相关问题