使用内部联接计算特定字段

时间:2017-05-08 20:14:34

标签: mysql sql

我有以下架构:

create table myapp_task
(
  title varchar(100) not null,
  state varchar(11) not null,
  estimate date not null,
  my_id int not null auto_increment
  primary key,
  road_map_id int not null,
  create_date date not null,
  constraint myapp_task_road_map_id_5e114978_fk_myapp_roadmap_rd_id
  foreign key (road_map_id) references myapp_roadmap (rd_id)
);
— auto-generated definition
create table myapp_roadmap
(
  rd_id int not null auto_increment
  primary key,
  name varchar(50) not null
);

我想要获取编号,一周开始和结束的create_date,所有任务的数量和就绪任务的数量(state ='ready / in_progress')

这是我的问题:

select DISTINCT week(create_date, 1) as week,
  SUBDATE(create_date, WEEKDAY(create_date)) as beginofweek,
  DATE(create_date + INTERVAL (6 - WEEKDAY(create_date)) DAY) as endofweek,
  SUM(state) as number,
  SUM(state = 'ready') as ready
from myapp_task 
inner join myapp_roadmap
  on myapp_task.road_map_id = myapp_roadmap.rd_id;

实际上,我只有现成任务的数量才有问题。

2 个答案:

答案 0 :(得分:3)

我认为你很接近:

select week(create_date, 1) as week,
    SUBDATE(create_date, WEEKDAY(create_date)) as beginofweek,
    DATE(create_date + INTERVAL (6 - WEEKDAY(create_date)) DAY) as endofweek,
    count(state) as number,
    SUM(CASE WHEN state = 'ready' THEN 1 ELSE 0 END) as ready,
    SUM(CASE WHEN state = 'in_progress' THEN 1 ELSE 0 END) as in_progress
FROM myapp_task inner join myapp_roadmap
    on myapp_task.road_map_id = myapp_roadmap.rd_id
GROUP BY week, beginofweek, endofweek

使用CASE语句,您可以单独添加statesready in_progress。此外,增加GROUP BY可确保计算一周。在这种情况下,我认为MySQL可能会在没有GROUP BY的情况下吐出正确的结果,但为什么要让它猜测你想要的东西。此外,如果您升级到MySQL 5.7+,那么在没有GROUP BY的情况下编写的查询将默认出错。

还摆脱了DISTINCT修饰符。谢谢@AaronDietz

答案 1 :(得分:0)

您应该查看aggregate functions

的使用情况

COUNT是返回行数的函数,并且为了获得状态总数的两个值以及等于'ready'的值,您需要使用不同的连接条件将表连接两次

那些未聚合的列需要包含在GROUP BY子句中。

select DISTINCT week(create_date, 1) as week,
SUBDATE(create_date, WEEKDAY(create_date)) as beginofweek,
DATE(create_date + INTERVAL (6 - WEEKDAY(create_date)) DAY) as endofweek,
COUNT(r1.state) AS number, 
COUNT(r2.state) AS ready
from myapp_roadmap inner join myapp_task r1
on r1.road_map_id = myapp_roadmap.rd_id
inner join myapp_task r2
on r2.road_map_id = myapp_roadmap.rd_id and r2.state = 'ready'
group by week, beginofweek, endofweek