0

I have a table that tracks the Current Work and Status of the work. So in my table column 'Current Work' captures the product name along with the different tasks being done on the product.

If the the Work has sub activities, the column 'Work Parent Name' is filled with the 'Current Work', else it remains blank if the Work is standalone. So the count needs to be taken only once either at the Work level or the sub activities level, hence cannot be used completely in an hierarchical path.

The 'Status' column is updated with the progress of either the work or the sub work.

![Work Table

Now, as the data is not properly structured, i am finding it a bit difficult to count the 'In Progress' status of Products. So if the status of any work or sub activity under the work is in progress, i want to count the Work to be in progress

So the output i am looking for is below :

![![![enter image description here

I tried to do self join but as the sub activities are same, i am getting wrong results. Is their any way i can achieve my result from this type of data-set.

user3454116
  • 184
  • 1
  • 12
  • Please read & act on [mcve]. What self joins did you try? When exactly is a row (w,c) in the query result in terms of what rows are in the base table? Please also edit to clarify per your comment on the guess/answer below. – philipxy Oct 01 '17 at 03:05
  • Possible duplicate of [What are the options for storing hierarchical data in a relational database?](https://stackoverflow.com/questions/4048151/what-are-the-options-for-storing-hierarchical-data-in-a-relational-database) But that is if there are arbitrary depths of subtypes; looks like you just have one here. – philipxy Oct 01 '17 at 03:07
  • I updated to show the columns of my output and i assume this as a unique question, as the work and activities are not defined and i had to count the 'In Progress' it either the Work or any Work with sub activities had the needed status. I hope this clarifies my question. – user3454116 Oct 01 '17 at 03:47
  • Unique? https://www.google.ca/search?q=current++work+parent+status+count+sql+query+table You don't seem to have acted on my 1st comment & its link. Your description is unclear re the result. (I said how to try to be clear.) Really, we must guess from the table format. You confuse names of things with names of columns & I really don't know what you mean by "semi-structured" & "not properly structured". PS Notice how this design would be a lot clearer if you had 2 separate tables, top level & next level? Notice how the solution has to decompose to those tables? Glad you got an answer. – philipxy Oct 01 '17 at 05:23
  • Please stop commenting. I got your feedback and will keep it in mind going forward. Thank you. – user3454116 Oct 01 '17 at 05:28

2 Answers2

0

Ok...I am a little confused as to what you are asking. Shouldn't product 5 have in progress of 2 if you are doing a count? Or are you just trying to get a 1 if any are in progress.

Try this...

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

or this if you want to include the in progress of the parent as well.

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

Either way the question is a little unclear. How does product 2 have a wip task "In Progress" but is not in progress itself?

Build script

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')

sqlfiddle link if you want to play with it... http://sqlfiddle.com/#!9/e0fa02/15 Hope this helps...

EDIT AFTER COMMENT:

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

Give this a whirl...

Also, if you want to see where all of the sub items are marked as In Progress

select w1.work as work
,if(w1.status = 'In Progress' or w2.status = 'In Progress',1,0) countInProgress
,@allInProgress := case when @allInProgress is null and w2.status = 'In Progress' then 1
                        when @allInProgress is null and (w2.status <> 'In Progress' or w2.status is null) then 0
                        when w2.status = 'In Progress' then @allInProgress * 1
                        when w2.status <> 'In Progress' then @allInProgress * 0
                        end allInProgress
from work w1 
left join work w2 on w1.work = w2.parent
where w1.parent is null
group by w1.work
  • Hi, The Product 2 is showing count as 1 because, either the work or the sub activity under the work is 'In Progress'. I checked your output, but it doesnot give me the desired result that i have shown in output. I want the count of 'In Progress' to be one for the Work even when the Work or sub activities under the work is 'In Progress'. Hope this clarifies the confusion. – user3454116 Oct 01 '17 at 02:15
  • Ok. So you don't want a count at all. You need an if statement. Will throw it together for you in a minute – beautiful.drifter Oct 01 '17 at 02:17
  • I updated the answer and added what I think you need at the bottom – beautiful.drifter Oct 01 '17 at 02:26
  • If you don't know what the question is asking then make a comment, don't post a guess as a purported answer. Also, please don't add updates, revise your answer. And tell the asker to edit clarifications into their question, not comments. (Here, @user3454116.) – philipxy Oct 01 '17 at 02:57
  • @philipxy So where should I put the tweek to the query. The answer I gave actually gave her what she was asking for...a count and I made certain assumptions which got the query 90% of the way there. I understood what she was asking, was just a little unclear on the output. – beautiful.drifter Oct 01 '17 at 03:07
  • Your last comment does not reflect understanding of what I wrote. My comment still applies. This time you were lucky that your answer wasn't too invalidated by asker clarifications. Guessing leads to unhelpful non-answers. On getting (sufficient) clarifications please edit your answer to the best form, which isn't to refer to a comment because as I said the comment shouldn't be there, its content should be edited into a best form question; incorporate into an intro, drop bad-guess content. If the asker doesn't edit theirs, you can. Nothing in my last comment is invalidated by yours. – philipxy Oct 01 '17 at 03:15
  • 'stackexchange why should i ask for clarification instead of answering' https://meta.stackexchange.com/q/143682/266284 https://meta.stackexchange.com/q/222116/266284 https://meta.stackexchange.com/q/214173/266284 – philipxy Oct 01 '17 at 03:22
  • @philipxy I appreciate the advice and will keep it in mind going forward. I would like to give you some advice as well. I literally cannot tell if you are trying to be helpful for someone new to this that is just trying to help someone with a query, but you sound like an angry troll hellbent on lighting in to someone and proving your point. If you are actually trying to be helpful, please work on your delivery. If you are just out to prove a point, stop, because you will just deter people from using the site. – beautiful.drifter Oct 01 '17 at 03:26
  • @beautiful.drifter Thanks for modifying the query, it gives me the desired result. I appreciate your quick help. Just wanted wanted to check, if their is a way to modify your query to give me only those Current Work, which has the Work and all the sub activities under the Work as 'In Progress'. So from my query i would get output as '1' for only Product 5. – user3454116 Oct 01 '17 at 04:14
  • @philipxy where should I put the answer to the comment above? I have the query. – beautiful.drifter Oct 01 '17 at 04:36
  • @user3454116 see bottom of answer – beautiful.drifter Oct 01 '17 at 04:42
  • @user3454116 In general, please when you want to ask something else, just post it as a new question. (And if you are an answerer, please tell them that.) Ie don't invalidate any reasonable answers. Here, there are no other answers affected and you are in touch with the answerer, so you two can hopefully just work out what the modified question is going to be it it's ok with the answerer.) (But this answer is very messy. Is this what you'd want to see as a question & answer?) – philipxy Oct 01 '17 at 04:59
  • @beautiful.drifter: Your second query works. Just out of curiosity to understand your query, how do i modify it to give me records, where any Work which doesn't have any sub activities and is 'In Progress' is also returned and also any Work which only has all of its sub activities as 'In Progress' is also returned. So if i update the input table for Product 2 and make 'Service' and 'Transportation' as 'in Progress', i would get the result 1 for Product 2, Product 4 and Product 5. You can just put your input in comment section for my reference. – user3454116 Oct 01 '17 at 16:31
  • I have unchecked the acceptance flag, as this answer doesn't fulfill my requirement when i have a Work, whose first activity is something other than 'In Progress'. I have updated the sqlfiddle (http://sqlfiddle.com/#!9/6dd171/2) to include Product 6. – user3454116 Oct 05 '17 at 20:20
  • How do you determine which activity is first? – beautiful.drifter Oct 07 '17 at 03:46
  • I was able to devise a query to fulfill my requirement. Thanks – user3454116 Oct 07 '17 at 19:59
0

I was able to achieve my requirement using two sub queries and combining through union function. I am not sure if this is the best or only way, but it gives me what i wanted and fulfills my requirement.

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;
user3454116
  • 184
  • 1
  • 12