【问题标题】:Insert subquery date according to day按天插入子查询日期
【发布时间】:2016-10-12 18:03:01
【问题描述】:

我想插入基于日期的子查询。另外,每个日期只能使用四次。一旦达到第四次,第五个值将使用同一天的另一个日期。换句话说,使用下周星期一的日期。例如,Monday6 JUNE 2016Monday13 JUNE 2016(您可以查看日历)。

我有一个查询,希望从presentation 表中获取基于presentationdatestartpresentationdateend 的日期列表:

select   a.presentationid,
         a.presentationday,
         to_char (a.presentationdatestart + delta, 'DD-MM-YYYY', 'NLS_CALENDAR=GREGORIAN') list_date
from     presentation a,
         (select     level - 1 as delta
          from       dual
          connect by level - 1 <= (select max (presentationdateend - presentationdatestart)
                                   from   presentation))
where    a.presentationdatestart + delta <= a.presentationdateend
and      a.presentationday = to_char(a.presentationdatestart + delta, 'fmDay')
order by a.presentationdatestart + delta,
         a.presentationid; --IMPORTANT!!!--

例如,

presentationday    presentationdatestart    presentationdateend
     Monday              01-05-2016             04-06-2016
    Tuesday              01-05-2016             04-06-2016
   Wednesday             01-05-2016             04-06-2016
   Thursday              01-05-2016             04-06-2016

查询结果将列出01-05-201604-06-2016 之间的所有可能日期:

Monday  02-05-2016
Tuesday 03-05-2016
Wednesday   04-05-2016
Thursday    05-05-2016
....
Monday      30-05-2016
Tuesday     31-05-2016
Wednesday   01-06-2016
Thursday    02-06-2016 (20 rows)

这是我的INSERT 查询:

insert into CSP600_SCHEDULE (studentID,
                             studentName, 
                             projectTitle,
                             supervisorID,
                             supervisorName,
                             examinerID,
                             examinerName,
                             exavailableID,
                             availableday,
                             availablestart,
                             availableend,
                             availabledate)   
select  '2013816591',
        'mong',
        'abc',
        '1004',
        'Sue',
        '1002',
        'hazlifah',
          2,
        'Monday', //BASED ON THIS DAY
        '12:00:00',
        '2:00:00',
         to_char (a.presentationdatestart + delta, 'DD-MM-YYYY', 'NLS_CALENDAR=GREGORIAN') list_date //FOR AVAILABLEDATE
from     presentation a,
         (select     level - 1 as delta
          from       dual
          connect by level - 1 <= (select max (presentationdateend - presentationdatestart)
                                   from   presentation))
where    a.presentationdatestart + delta <= a.presentationdateend
and      a.presentationday = to_char(a.presentationdatestart + delta, 'fmDay')
order by a.presentationdatestart + delta,
         a.presentationid;

此查询成功添加了 20 行,因为所有可能的日期都是 20 行。我想修改查询以便能够基于availableDay 插入,并且每个日期对于每个不同的studentID 只能使用四次。

CSP600_SCHEDULE 中的可能结果(我正在删除不相关的列以提高可读性):

StudentID   StudentName     availableDay      availableDate
  2013         abc             Monday           01-05-2016
  2014         def             Monday           01-05-2016
  2015         ghi             Monday           01-05-2016
  2016         klm             Monday           01-05-2016
  2010         nop            Tuesday           02-05-2016
  2017         qrs            Tuesday           02-05-2016
  2018         tuv            Tuesday           02-05-2016
  2019         wxy            Tuesday           02-05-2016
  .....
  2039         rrr             Monday           09-05-2016
  ..... 

你可以查看日历:)

【问题讨论】:

    标签: date plsql oracle11g subquery insert-select


    【解决方案1】:

    认为您要求的是列出您的学生,然后将他们分成 4 组 - 然后将每批分配给一个日期。对吗?

    在这种情况下,这样的事情应该可以工作(我使用表列表作为学生姓名,这样我就不需要将任何数据插入到自定义表中):

    WITH students AS
    (SELECT table_name 
     FROM all_tables
     WHERE rownum < 100
     )
    SELECT 
     table_name
    ,SYSDATE + (CEIL(rownum/4) -1)
    FROM
     students
    ;
    

    希望对你有帮助

    ...好吧,按照你的 cmets,我认为这可能是一个更好的解决方案:

    WITH students AS
    (SELECT table_name student_name
     FROM all_tables
     WHERE rownum < 100
     )
    , dates AS
    (SELECT TRUNC(sysdate) appointment_date from dual UNION
     SELECT TRUNC(sysdate+2) from dual UNION
     SELECT TRUNC(sysdate+4) from dual UNION
     SELECT TRUNC(sysdate+6) from dual UNION
     SELECT TRUNC(sysdate+8) from dual UNION
     SELECT TRUNC(sysdate+10) from dual UNION
     SELECT TRUNC(sysdate+12) from dual UNION
     SELECT TRUNC(sysdate+14) from dual 
    )
    SELECT 
     s.student_name
    ,d.appointment_date
    FROM
     --get a list of students each with a sequential row number, ordered by student name 
     (SELECT
       student_name
      ,ROW_NUMBER() OVER (ORDER BY student_name) rn
     FROM students
     )     s
     --get a list of available dates with a sequential row number, ordered by date
    ,(SELECT
       appointment_date
      ,ROW_NUMBER() OVER (ORDER BY appointment_date) rn
     FROM dates
     ) d
    WHERE 1=1
    --allocate the first four students to date rownumber1, next four students to date rownumber 2...
    AND CEIL(s.rn/4) = d.rn 
    ;
    

    【讨论】:

    • 感谢您抽出宝贵时间 :) 老实说,我不熟悉这种查询...这是如何工作的?
    • 我想我理解您的查询.. 但我担心的是日期是从presentationdatestartpresentation 表中检索到的.. 那么,我该如何修改查询?因为如果我通过更改查询直接修改为使用presentation 表,将有4 行,因为presentation 表中只有4 行可用。 (我不知道怎么解释:()
    • 好的,所以我的第一次尝试对你来说不太成功,但有用的一点是我尝试将学生分成四组(我认为这是你问题的关键)。您希望将第一个可用日期基于 PRESENTATION.presentationDateStart 而不是使用 sysdate - 正确吗?
    • 是的,使用presentation 表中的日期...我希望您的意思是分成四个是允许四个学生有一个日期:) 但是您的查询设法将日期分成四个
    • 其实不一定把它们分成四个。我主要关心的是当我insert 查询时,一个日期将被使用四次。并且日期必须与availableday 平行。你明白我的意思吗?
    猜你喜欢
    • 2011-04-10
    • 2021-08-03
    • 1970-01-01
    • 2016-09-11
    • 2021-04-16
    • 2011-04-23
    • 2013-10-24
    • 2016-09-21
    • 1970-01-01
    相关资源
    最近更新 更多