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 如何根据子查询中的列进行分组_Sql_Postgresql - Fatal编程技术网

Sql 如何根据子查询中的列进行分组

Sql 如何根据子查询中的列进行分组,sql,postgresql,Sql,Postgresql,我有一个任务表 tasks_id | start_time_id | end_time_id | start_date | end_date t1 | st_1 | et_1 | 20180903 | 20180903 t2 | st_2 | et_2 | 20180903 | 20180903 t3 | st_3 | et_3 | 20180903

我有一个任务表

tasks_id | start_time_id | end_time_id | start_date | end_date

t1       | st_1          | et_1        | 20180903   | 20180903
t2       | st_2          | et_2        | 20180903   | 20180903
t3       | st_3          | et_3        | 20180903   | 20180903
t4       | st_4          | et_4        | 20180903   | 20180903
t5       | st_5          | et_5        | 20180903   | 20180903
t6       | st_6          | et_6        | 20180903   | 20180904
start\u-time
end\u-time
是与
time\u表
连接的ID,用于获取类似于

   time_id   | military_hour 
   st1       | 0
   st2       | 2
   st3       | 7
   st4       | 16
   st5       | 18
   st6       | 23
   et1       | 0
   et2       | 2
   et3       | 8
   et4       | 16
   et5       | 18
   et6       | 0  
如果我想知道
开始时间id
结束时间id
的军事时间,我可以两次加入
任务
表和
时间表

SELECT        t1.tasks_id as task_inst_id,
              t1.start_time_id,
              t1.end_time_id,
              t1.end_date as end_date,
              t1.start_date as start_date
      FROM task_instances t1
      INNER JOIN time_table td1 
              ON t1.start_time_id = td1.time_id
      INNER JOIN time_table td2 
              ON t1.end_time_id = td2.time_id 
我可以将军事时间划分为每个窗口4小时,因此一天中有6个窗口或军事时间组

  (FLOOR(military_hour / 4)) AS military_hour_group
我想知道如果我度过了某一天,在这些窗口中开始或结束的所有任务的编号

我试过了

SELECT
tq1.start_military_hour_group,
tq1.end_date,
COUNT(tq1.task_inst_id) as no_of_tasks
FROM
(
SELECT        t1.tasks_id as task_inst_id,
              t1.start_time_id,
              t1.end_time_id,
              t1.end_date as end_date,
              (FLOOR(td1.military_hour / 4)*4) AS start_military_hour_group,
              (FLOOR(td2.military_hour / 4)*4) AS end_military_hour_group
      FROM task_instances t1
      INNER JOIN time_table td1 
              ON t1.start_time_id = td1.time_id
      INNER JOIN time_table td2 
              ON t1.end_time_id = td2.time_id 

      /* I don't know how to put the where condition */

      WHERE t1.end_date = '20180903':: int 
)tq1
GROUP BY tq1.start_military_hour_group,tq1.end_date
ORDER BY tq1.end_date,tq1.start_military_hour_group;
我知道我遗漏了什么,但到底是什么

我加入了两次,所以我想它会为任务表中的同一行创建两行,我应该选择结束日期还是开始日期?

请解释一下

例如,对于样本集

0 - 3 group - 2 tasks
4-7 group - 1 task
8-11 group - 0 
12-15 group - 0
16 - 19 group - 2 taks
20-23 group - 1 task

我会用另一种方式。这段代码更简单,尽管可能比加入两次效率更低

select  count(distinct ti.tasks_id), floor(td.military_hour/4)*4 time_group
from time_dimension td
join time_instance ti on td.time_id in (ti.start_time_id, ti.end_time_id)
group by  floor(td.military_hour/4)*4 time_group
where td.end_date = '2018090'

第一件事。您应该重新考虑您的数据模型-开始时间id和结束时间id以及包含冗余数据的单独表(时间表)不是一个好的设计。您可以将小时作为开始时间和结束时间

现在,让我们解决实际设计中的问题

with time_groups as (select * from (values (0, '0 - 3 group'),
                                           (1, '4 - 7 group'),
                                           (2, '8 - 11 group'),
                                           (3, '12 - 15 group'),
                                           (4, '16 - 19 group'),
                                           (5, '20 - 23 group')) a (id, name))

select tg.name, coalesce(tasks,0) tasks
  from (select tt1.military_hour/4 time_group_id, count(*)  tasks
          from task_instances ti
          LEFT join time_table tt1 on ti.start_time_id=tt1.time_id
          LEFT JOIN time_table tt2 on ti.end_time_id=tt2.time_id
         where ti.end_date='20180903' or ti.end_date is null
         group by tt1.military_hour/4
         order by 1) a
  right join time_groups tg on a.time_group_id=tg.id

您的数据的预期输出是什么?@RadimBača我刚刚更新过。请看。@a_horse_,没有名字,上面写着24小时格式0-23。然后我把他们分成4个小时的小组,每个小组使用
(FLOOR(millitary_hour/4))作为millitary_hour\u group
。它存储在
time\u table
@a\u horse\u中,我不知道它的名字。这只是表模式使用的名称。您可以使用
WIDTH\u BUCKET(表达式,最小值,最大值,BUCKET)
WIDTH\u BUCKET(军事小时,0,24,6)一样作为BUCKET
,它给出了
军事小时
所在的BUCKET的编号。但它并没有给我任务的总数:(.我给了我一个时间计数\u id,然后将计数改为计数(不同的任务\u id),但是,这可能不准确。让我考虑一下