如何对子查询中的列进行分组

时间:2018-09-12 06:20:52

标签: 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   | 20180903
t4       | st_4          | et_4        | 20180903   | 20180903
t5       | st_5          | et_5        | 20180903   | 20180903
t6       | st_6          | et_6        | 20180903   | 20180904

start_timeend_time是ID,它们与time_table一起获得

   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  

如果我想知道taskstime_table的军事时间,我可以与start_time_idend_time_id表一起加入两次。 / p>

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

我想知道no of all the tasks that either started or ended in those windows if I pass a particular day

我尝试过

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;

我知道我想念什么,但究竟是什么?

我要加入两次,所以我猜它为任务表中的同一行创建了2行,我也应该使用end_date或start_date吗?

请解释。

例如对于样品集

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

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

我会另辟go径。这段代码更简单,尽管效率可能不如两次。

<PropertyGroup>
  <CompileDependsOn>
    $(CompileDependsOn);
    WebpackBuild;
  </CompileDependsOn>
</PropertyGroup>
<Target Name="WebpackBuild" DependsOnTargets="CompileTypeScript">
  <Exec Condition="$(Configuration) == 'Release'" Command="npm run buildProd" />
</Target>
<Target Name="BeforeBuild">
  <Exec Condition="$(Configuration) == 'Debug'" Command="npm run buildDev" />
</Target>