Sql 按周分组数据

Sql 按周分组数据,sql,oracle,week-number,Sql,Oracle,Week Number,我正在寻找一种方法,将下面的emp_出席行分组为周一至周日的几周 我在网上看到了一些关于“IW”格式的东西,但我认为这不允许我分组,也许我做错了什么。此外,12312020星期四和01012021星期五等日期应分组在一起,因为它们介于星期一和星期日之间,但年份不同 我当前的代码是对所有数据求和,并生成以下输出 select e.employee_id, e.first_name, e.last_name,

我正在寻找一种方法,将下面的emp_出席行分组为周一至周日的几周

我在网上看到了一些关于“IW”格式的东西,但我认为这不允许我分组,也许我做错了什么。此外,12312020星期四和01012021星期五等日期应分组在一起,因为它们介于星期一和星期日之间,但年份不同

我当前的代码是对所有数据求和,并生成以下输出

  select   e.employee_id, 
               e.first_name,    
               e.last_name,

        trunc(sum(a.end_date - a.start_date) * 24) hours,

       trunc(mod(sum(a.end_date - a.start_date) * 24 * 60,60)) minutes,

        round(mod(sum(a.end_date - a.start_date) * 24 * 60 * 60,60)) seconds

 from    employees e,       emp_attendance a

   where a.employee_id = e.employee_id 

  group by e.employee_id, 
           e.first_name, e.last_name

 order by e.employee_id, 
                  e.first_name,   
                e.last_name;


EMPLOYEE_ID    FIRST_NAME    
LAST_NAME    HOURS    
MINUTES    SECONDS
  1    John    Doe    128    51    19
我正在寻找这个输出。注意:对于组中的每一行,我需要相同的组id和组的开始日期(周一)和结束日期(周日),以便在需要时可以追溯数据的来源

如果没有员工的emp_考勤记录,请不要添加空行。在我的示例中,虽然员工2和3存在,但他们不应该有输出

感谢所有回答的人

GROUP_ID  
EMPLOYEE_ID    FIRST_NAME    
LAST_NAME    HOURS    MINUTES    SECONDS.    
START_DATE END_DATE 
 1 1    John    Doe    46    0    58 07202020 07262020
2 1    John    Doe    73    37    14 07272020 08022020 
3 1    John    Doe  9    13    7 08032020 08082020



ALTER SESSION SET NLS_DATE_FORMAT = 'MMDDYYYY HH24:MI:SS';

  Create table employees(
  employee_id Number(6),
  first_name VARCHAR2(20),
  last_name VARCHAR2(20),
  hourly_rate NUMBER
 );

  INSERT INTO employees(
   employee_id,
   first_name,
   last_name,
   hourly_rate)
  VALUES 
  (1, 'John', 'Doe', 55.05);


  INSERT INTO employees(
   employee_id,
   first_name,
   last_name,
   hourly_rate)
  VALUES 
  (2, 'Jane', 'Smith', 45.50);


  INSERT INTO employees(
   employee_id,
   first_name,
   last_name,
   hourly_rate)
  VALUES 
  (3, 'Mike', 'Jones', 25.00);


  create table emp_attendance(
    employee_id NUMBER(6),
    start_date DATE,
   end_date DATE
   );

INSERT INTO emp_attendance(
  employee_id,
  start_date,
  end_date)
  VALUES 
  (1,
  TO_DATE('08032020 12:12:12', 'MMDDYYYY HH24:MI:SS'),

 TO_DATE('08032020 21:25:19', 'MMDDYYYY HH24:MI:SS'));



  INSERT INTO emp_attendance(
  employee_id,
  start_date,
  end_date)
  VALUES 
  (1,
  TO_DATE('08022020 12:12:12', 'MMDDYYYY HH24:MI:SS'),

 TO_DATE('08032020 19:25:19', 'MMDDYYYY HH24:MI:SS'));


  INSERT INTO emp_attendance(
  employee_id,
  start_date,
  end_date)
  VALUES 
  (1,
  TO_DATE('07212020 07:22:22', 'MMDDYYYY HH24:MI:SS'),

 TO_DATE('07212020 14:49:13', 'MMDDYYYY HH24:MI:SS'));

  INSERT INTO emp_attendance(
  employee_id,
  start_date,
  end_date)
  VALUES 
  (1,
  TO_DATE('07222020 08:08:43', 'MMDDYYYY HH24:MI:SS'),

 TO_DATE('07222020 16:15:55', 'MMDDYYYY HH24:MI:SS'));

  INSERT INTO emp_attendance(
  employee_id,
  start_date,
  end_date)
  VALUES 
  (1,
  TO_DATE('07232020 08:18:17', 'MMDDYYYY HH24:MI:SS'),

  TO_DATE('07232020 15:58:16', 'MMDDYYYY HH24:MI:SS'));

  INSERT INTO emp_attendance(
  employee_id,
  start_date,
  end_date)
  VALUES 
  (1,
  TO_DATE('07242020 10:50:15', 'MMDDYYYY HH24:MI:SS'),

  TO_DATE('07242020 18:21:41', 'MMDDYYYY HH24:MI:SS'));

  INSERT INTO emp_attendance(
 employee_id,
 start_date,
 end_date)
VALUES 
   (1,
 TO_DATE('07252020 18:06:11', 'MMDDYYYY HH24:MI:SS'),

  TO_DATE('07262020 01:34:37', 'MMDDYYYY HH24:MI:SS'));

  INSERT INTO emp_attendance(
  employee_id,
  start_date,
  end_date)
  VALUES 
  (1,
  TO_DATE('07262020 10:57:07', 'MMDDYYYY HH24:MI:SS'),

  TO_DATE('07262020 18:44:11', 'MMDDYYYY HH24:MI:SS'));

  INSERT INTO emp_attendance(
  employee_id,
  start_date,
  end_date)
  VALUES 
  (1,
  TO_DATE('07272020 09:35:44', 'MMDDYYYY HH24:MI:SS'),

  TO_DATE('07272020 16:14:13', 'MMDDYYYY HH24:MI:SS'));

  INSERT INTO emp_attendance(
  employee_id,
  start_date,
  end_date)
  VALUES 
  (1,
  TO_DATE('07282020 07:08:31', 'MMDDYYYY HH24:MI:SS'),

  TO_DATE('07282020 17:17:12', 'MMDDYYYY HH24:MI:SS'));

  INSERT INTO emp_attendance(
  employee_id,
  start_date,
  end_date)
  VALUES 
  (1,
  TO_DATE('07292020 05:38:27', 'MMDDYYYY HH24:MI:SS'),

  TO_DATE('07292020 13:06:49', 'MMDDYYYY HH24:MI:SS'));

  INSERT INTO emp_attendance(
  employee_id,
  start_date,
  end_date)
  VALUES 
  (1,
  TO_DATE('07302020 08:11:51', 'MMDDYYYY HH24:MI:SS'),

  TO_DATE('07302020 18:29:40', 'MMDDYYYY HH24:MI:SS'));

  INSERT INTO emp_attendance(
  employee_id,
  start_date,
  end_date)
  VALUES 
  (1,
  TO_DATE('07312020 18:01:51', 'MMDDYYYY HH24:MI:SS'),

  TO_DATE('08012020 01:52:37', 'MMDDYYYY HH24:MI:SS'));

有很多帖子都有类似的主题,所以我会在发布时链接它们->

  • 这篇文章可以帮助您按周分组数据并进行分组计算
  • 然后可以使用mySQL ROUND()函数将参数设置为舍入到最接近10的位置。在这里可以找到文档

  • 有很多帖子都有类似的主题,所以我会在发布时链接它们->

  • 这篇文章可以帮助您按周分组数据并进行分组计算
  • 然后可以使用mySQL ROUND()函数将参数设置为舍入到最接近10的位置。在这里可以找到文档

  • 在上面的数据库结构中,可以使用表中的“开始日期”列 emp_出勤率,计算当前周数,然后根据周数分组

    您可以将附加参数与round函数一起使用 舍入(列名称,舍入数) 对第二个参数使用负值

    -1表示整数到10秒

    -2表示整数到100秒

    -3表示整数到1000秒

    等等

    查询应类似于以下内容:

    select to_char(a.start_date, 'WW') weekNumber, e.employee_id, e.first_name,  e.last_name, 
     trunc(sum(a.end_date - a.start_date) * 24) hours, 
    trunc(mod(sum(a.end_date - a.start_date) * 24 * 60,60)) minutes,          
    round(mod(sum(a.end_date - a.start_date) * 24 * 60,60), -1) rounded_minutes,   
    round(mod(sum(a.end_date - a.start_date) * 24 * 60 * 60,60)) seconds 
    from employees e, emp_attendance a 
    where a.employee_id = e.employee_id
    group by e.employee_id, e.first_name, e.last_name ,to_char(a.start_date, 'WW')
    -- order by first column = weekNumber then by other columns
    order by 1, e.employee_id, e.first_name,  e.last_name;
    

    在上面的数据库结构中,可以使用表中的“开始日期”列 emp_出勤率,计算当前周数,然后根据周数分组

    您可以将附加参数与round函数一起使用 舍入(列名称,舍入数) 对第二个参数使用负值

    -1表示整数到10秒

    -2表示整数到100秒

    -3表示整数到1000秒

    等等

    查询应类似于以下内容:

    select to_char(a.start_date, 'WW') weekNumber, e.employee_id, e.first_name,  e.last_name, 
     trunc(sum(a.end_date - a.start_date) * 24) hours, 
    trunc(mod(sum(a.end_date - a.start_date) * 24 * 60,60)) minutes,          
    round(mod(sum(a.end_date - a.start_date) * 24 * 60,60), -1) rounded_minutes,   
    round(mod(sum(a.end_date - a.start_date) * 24 * 60 * 60,60)) seconds 
    from employees e, emp_attendance a 
    where a.employee_id = e.employee_id
    group by e.employee_id, e.first_name, e.last_name ,to_char(a.start_date, 'WW')
    -- order by first column = weekNumber then by other columns
    order by 1, e.employee_id, e.first_name,  e.last_name;
    

    您可以获得为期一周的周一和ISO周;然后按该字段以及其他字段分组:

    select e.employee_id,
      e.first_name,
      e.last_name,
      trunc(a.start_date, 'IW') as week,
      trunc(sum(a.end_date - a.start_date) * 24) hours,
      trunc(mod(sum(a.end_date - a.start_date) * 24 * 60,60)) minutes,
      round(mod(sum(a.end_date - a.start_date) * 24 * 60 * 60,60)) seconds
    from employees e
    join emp_attendance a on a.employee_id = e.employee_id
    group by e.employee_id, e.first_name, e.last_name, trunc(a.start_date, 'IW')
    order by e.employee_id, e.first_name, e.last_name, trunc(a.start_date, 'IW');
    
    要获得所需的输出,您可以操纵截断的日期,并为组ID添加一个
    row\u number()

    select row_number() over (order by trunc(a.start_date, 'IW')) as group_id,
      e.employee_id,
      e.first_name,
      e.last_name,
      trunc(sum(a.end_date - a.start_date) * 24) hours,
      trunc(mod(sum(a.end_date - a.start_date) * 24 * 60,60)) minutes,
      round(mod(sum(a.end_date - a.start_date) * 24 * 60 * 60,60)) seconds,
      to_char(trunc(a.start_date, 'IW'), 'MMDDYYYY') as start_date,
      to_char(trunc(a.start_date, 'IW') + 6, 'MMDDYYYY') as end_date
    from employees e
    join emp_attendance a on a.employee_id = e.employee_id
    group by e.employee_id, e.first_name, e.last_name, trunc(a.start_date, 'IW')
    order by e.employee_id, e.first_name, e.last_name;
    

    对于当前数据;和。

    您可以获得为期一周的周一和ISO周;然后按该字段以及其他字段分组:

    select e.employee_id,
      e.first_name,
      e.last_name,
      trunc(a.start_date, 'IW') as week,
      trunc(sum(a.end_date - a.start_date) * 24) hours,
      trunc(mod(sum(a.end_date - a.start_date) * 24 * 60,60)) minutes,
      round(mod(sum(a.end_date - a.start_date) * 24 * 60 * 60,60)) seconds
    from employees e
    join emp_attendance a on a.employee_id = e.employee_id
    group by e.employee_id, e.first_name, e.last_name, trunc(a.start_date, 'IW')
    order by e.employee_id, e.first_name, e.last_name, trunc(a.start_date, 'IW');
    
    要获得所需的输出,您可以操纵截断的日期,并为组ID添加一个
    row\u number()

    select row_number() over (order by trunc(a.start_date, 'IW')) as group_id,
      e.employee_id,
      e.first_name,
      e.last_name,
      trunc(sum(a.end_date - a.start_date) * 24) hours,
      trunc(mod(sum(a.end_date - a.start_date) * 24 * 60,60)) minutes,
      round(mod(sum(a.end_date - a.start_date) * 24 * 60 * 60,60)) seconds,
      to_char(trunc(a.start_date, 'IW'), 'MMDDYYYY') as start_date,
      to_char(trunc(a.start_date, 'IW') + 6, 'MMDDYYYY') as end_date
    from employees e
    join emp_attendance a on a.employee_id = e.employee_id
    group by e.employee_id, e.first_name, e.last_name, trunc(a.start_date, 'IW')
    order by e.employee_id, e.first_name, e.last_name;
    

    对于当前数据;和。

    谢谢,但这些命令是特定于sql server的,我正在运行Oracle谢谢,但这些命令是特定于sql server的,我正在运行Oracle(最好包含数据的预期结果),最好是原始数据的表格表示,以及insert语句)。你是否希望每周总共有一次;还是每个员工每周一次?(如果员工在给定的一周内没有时间怎么办-显示为零?)?或者您想在两周内拆分该行,并在每一周内留出适当的时间?@Alex重新格式化并添加了更多详细信息(最好包括数据的预期结果),最好是原始数据的表格表示,以及insert语句)。你是否希望每周总共有一次;还是每个员工每周一次?(如果员工在给定的一周内没有时间怎么办-显示为零?)?或者你想把这一行在两周内分开,每一周都有适当的时间?@Alex重新格式化并添加了更多细节。感谢您的专业知识和详细解释。感谢您的专业知识和详细解释