查询中的层次结构以获取唯一计数

时间:2017-10-01 01:08:41

标签: mysql self-join

我有一张表来跟踪工作的当前工作和状态。因此,在我的表格列中,“当前工作”会捕获产品名称以及在产品上执行的不同任务。

如果工作有子活动,则“工作父姓”列填充“当前工作”,否则如果工作是独立的,则它仍为空白。因此,计数只需要在工作级别或子活动级别进行一次,因此不能在分层路径中完全使用。

“状态”列将根据工作或子工作的进度进行更新。

![Work Table

现在,由于数据结构不合理,我发现计算产品的“进行中”状态有点困难。因此,如果工作中的任何工作或子活动的状态正在进行中,我想计算正在进行的工作

所以我想要的输出如下:

![![![enter image description here

我试图进行自我加入,但由于子活动是相同的,我得到了错误的结果。他们是否可以通过这种类型的数据集实现我的结果。

2 个答案:

答案 0 :(得分:0)

好的......我对你的要求感到有些困惑。如果您正在进行计数,那么产品5是否还有2个进展?或者你是否正试图获得1,如果有任何进展。

试试这个......

.title-slide h3:nth-of-type(2) {
    position: absolute;
    top: 0;
}

或者如果你想包括父母的进行中。

select w1.work as work, count(*) countInProgress
from work w1 
inner join work w2 on w1.work = w2.parent
where w2.status = 'In Progress'
group by w1.work

无论哪种方式,这个问题都有点不清楚。产品2如何进行wip任务"进行中"但是它本身没有进展?

构建脚本

select workItem, count(*) countInProgress from
(
select work, @workItem := if(parent is not null,parent,work) workItem
, status
from work
) t 
where status = 'In Progress'
group by workItem

sqlfiddle链接,如果你想玩它... http://sqlfiddle.com/#!9/e0fa02/15 希望这会有所帮助...

评论后编辑:

CREATE TABLE work (work varchar(20), parent varchar(20), status varchar(20));
INSERT INTO work VALUES
('Product 1',null,'In Progress'),
('Service', 'Product 1','Completed'),
('Delivery', 'Product 1', 'In Progress'),
('Transportation', 'Product 1', 'Completed'),
('Product 2',null,'In Progress'),
('Service', 'Product 2',''),
('Delivery', 'Product 2', 'In Progress'),
('Transportation', 'Product 2', ''),
('Product 3',null,'Completed'),
('Product 4',null,'In Progress'),
('Product 5',null,'In Progress'),
('Delivery', 'Product 5', 'In Progress'),
('Transportation', 'Product 5', 'In Progress')

给它一个旋转...

此外,如果您想查看所有子项目标记为正在进行中的位置

select w1.work as work
,if(w1.status = 'In Progress' or w2.status = 'In Progress',1,0) countInProgress
from work w1 
left join work w2 on w1.work = w2.parent
where w1.parent is null
group by w1.work

答案 1 :(得分:0)

我能够使用两个子查询并通过union函数组合来实现我的要求。我不确定这是最好还是唯一的方式,但它给了我想要的东西并满足了我的要求。

SELECT c.work,
COUNT(
             CASE WHEN w2.status = 'In Progress'
                  THEN '1'
              END) AS inprogress_count
FROM WORK c
INNER JOIN WORK w2 ON c.work = w2.parent
GROUP BY c.work
HAVING  COUNT(
             CASE WHEN w2.status = 'In Progress'
                  THEN '1'
              END) <> 0
UNION 
SELECT w2.work,
COUNT(
            CASE WHEN w2.status = 'In Progress'
                  THEN '1'
              END) AS inprogress_count           
FROM WORK w2
WHERE WORK NOT IN (
SELECT c.work
FROM WORK c
INNER JOIN WORK w2 ON c.work = w2.parent
GROUP BY c.work
HAVING  COUNT(
             CASE WHEN w2.status = 'In Progress'
                  THEN '1'
              END) <> 0)
AND parent IS NULL
GROUP BY w2.work;