Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL:如何按时间间隔30分钟选择员工和组的时间范围_Sql_Postgresql - Fatal编程技术网

SQL:如何按时间间隔30分钟选择员工和组的时间范围

SQL:如何按时间间隔30分钟选择员工和组的时间范围,sql,postgresql,Sql,Postgresql,我有三列,time-intimestamp、time-outtimestamp和employee。 我需要得到在特定时间范围内每隔30分钟工作的员工人数。例如: employee_id timein timeout 101 10:10 12:59 102 9:07 12:16

我有三列,time-intimestamp、time-outtimestamp和employee。 我需要得到在特定时间范围内每隔30分钟工作的员工人数。例如:

    employee_id              timein              timeout
    101                      10:10               12:59
    102                       9:07               12:16
    103                      11:16               12:08
(113, '13:00', '13:01'),
(113, '13:12', '13:15'),
(113, '13:22', '13:26')
我需要一个查询,将给我这个结果

    timeframe         count(employee_id)
    09:00                    1
    09:30                    1
    10:00                    2
    10:30                    2
    11:00                    3
    11:30                    3
    12:00                    3
    12:30                    1

我真的希望我说清楚了。谢谢

试试这样的东西

SELECT timeframe,
COUNT (employee_id)
FROM employee a
RIGHT JOIN
(SELECT *
 FROM generate_series (TIMESTAMP '2017-09-01 09:00:00', 
                       TIMESTAMP '2017-09-01 17:00:00', 
               INTERVAL '0.5 HOUR' ) AS timeframe) b 
                 ON b.timeframe >=  timein
                 AND b.timeframe <= timeout
GROUP BY timeframe
ORDER BY timeframe ;
请参阅此演示:

后者在13:30开始,14:00结束,因此包含在13:30时间段内,但不包含在14:00时间段内

问题可能是在同一时间段内多次开始和完成一项工作的员工经常休息,例如:

    employee_id              timein              timeout
    101                      10:10               12:59
    102                       9:07               12:16
    103                      11:16               12:08
(113, '13:00', '13:01'),
(113, '13:12', '13:15'),
(113, '13:22', '13:26')
对于这种情况,您需要使用:countDISTINCT employee\u id统计不同的员工

我根据本地数据样本进行了测试

employee_id | in_time  | out_time 
-------------+----------+----------
         101 | 09:07:00 | 12:08:00
         102 | 10:07:00 | 17:08:00
         103 | 12:07:00 | 17:08:00
         104 | 12:07:00 | 17:08:00
         105 | 10:07:00 | 17:08:00
查询的输出

time_frame | count 
------------+-------
 07:01:00   |     2
 03:01:00   |     1
 05:01:00   |     2
您可以在查找差异时包含相应的舍入逻辑

PostgreSQL 9.6架构设置:

问题1:


请问为什么没有日期?如果一名员工在23:00到07:00之间上夜班会发生什么?嗨,对不起,我这样做只是为了让它更快。也没有夜班。它只从早上8点到晚上11点。这很有效!但有没有办法让他们在15分钟内结束?例如:一个人在12:02下班,他将在12:30组登记。有没有办法做到这一点?endshift:12:02=12:00,12:16=12:30@RodDivinagracia:参考此链接了解一些信息:当我尝试使用一个时间戳执行此操作时如何?例如:同一时期的时间间隔数。我试着编辑你的查询,但它给了我很大的值。嗨,这很好用!顺便说一句,如果我删除超时表,只是为了看看有多少人在同一时间段30分钟的时间间隔内超时,我该如何编辑它?
employee_id | in_time  | out_time 
-------------+----------+----------
         101 | 09:07:00 | 12:08:00
         102 | 10:07:00 | 17:08:00
         103 | 12:07:00 | 17:08:00
         104 | 12:07:00 | 17:08:00
         105 | 10:07:00 | 17:08:00
time_frame | count 
------------+-------
 07:01:00   |     2
 03:01:00   |     1
 05:01:00   |     2
CREATE TABLE emp_time
    ("employee_id" int, "timein" time, "timeout" time)
;

INSERT INTO emp_time
    ("employee_id", "timein", "timeout")
VALUES
    (101, '10:10', '12:59'),
    (102, '9:07', '12:16'),
    (103, '11:16', '12:08')
;
SELECT 
      slot_start
    , slot_end
    , count(employee_id)
FROM  (
      SELECT slot_start, slot_start + INTERVAL '30 MINUTE' slot_end
      FROM generate_series (TIMESTAMP '2017-01-01 09:00:00', TIMESTAMP '2017-01-01 16:30:00', INTERVAL '30 MINUTE' ) AS slot_start
      ) t 
LEFT JOIN emp_time et ON et.timein < t.slot_end::time and et.timeout > t.slot_start::time
GROUP BY
      slot_start
    , slot_end
ORDER BY
      slot_start
    , slot_end
;
|           slot_start |             slot_end | count |
|----------------------|----------------------|-------|
| 2017-01-01T09:00:00Z | 2017-01-01T09:30:00Z |     1 |
| 2017-01-01T09:30:00Z | 2017-01-01T10:00:00Z |     1 |
| 2017-01-01T10:00:00Z | 2017-01-01T10:30:00Z |     2 |
| 2017-01-01T10:30:00Z | 2017-01-01T11:00:00Z |     2 |
| 2017-01-01T11:00:00Z | 2017-01-01T11:30:00Z |     3 |
| 2017-01-01T11:30:00Z | 2017-01-01T12:00:00Z |     3 |
| 2017-01-01T12:00:00Z | 2017-01-01T12:30:00Z |     3 |
| 2017-01-01T12:30:00Z | 2017-01-01T13:00:00Z |     1 |
| 2017-01-01T13:00:00Z | 2017-01-01T13:30:00Z |     0 |
| 2017-01-01T13:30:00Z | 2017-01-01T14:00:00Z |     0 |
| 2017-01-01T14:00:00Z | 2017-01-01T14:30:00Z |     0 |
| 2017-01-01T14:30:00Z | 2017-01-01T15:00:00Z |     0 |
| 2017-01-01T15:00:00Z | 2017-01-01T15:30:00Z |     0 |
| 2017-01-01T15:30:00Z | 2017-01-01T16:00:00Z |     0 |
| 2017-01-01T16:00:00Z | 2017-01-01T16:30:00Z |     0 |
| 2017-01-01T16:30:00Z | 2017-01-01T17:00:00Z |     0 |