Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Ranking Problem

Author  Topic 

Onamuji
Aged Yak Warrior

504 Posts

Posted - 2002-04-01 : 09:37:41
To solve the current problem at hand I tried to apply the ranking idea to it, this sort of worked however it does not handle certain cases which I am having trouble coding for. So any help will be appreciated.

Here's the problem, I have an old table that we use for project approvals, I am in the process of converting this table to a more robust and scalable version. Here's the vital old portion.

workflow
- project_id
- user_id
- step
- action
- date_processed

- next_state
- prev_state
The new version is these essential columns (there are about 15 other columns in the old table that are used for the application to track the workflow. In the new one this tracking is eliminated and combined. Here's some sample data from the old one.

project_id user_id step action date_processed next_state prev_state
---------- ------- ---- ------ ------------------- ---------- ----------
1 1 1 a 04/01/2002 05:35:00 2 NULL
1 2 2 a 04/01/2002 06:00:00 3 1
1 3 3 a 04/01/2002 06:05:00 NULL 2

It repeats like this for almost every project, has a user, a step level for the user's interaction and a date they either approved or rejected the project. We are just dealing with the approved projects right now. The ranking works well for this (you ask why use ranking algorithm to get the step when the step is already in order, well not in all of them. The step may start at 5 then jump to 7 then to 50 and such. (Bad programming on creators part) this is why I used the ranking algortihm. Now however there are instances where users may be grouped into the same step. Also users may request more information and the step goes back to the first step and after first step approves it it goes back to the step that requested more info. example:

project_id user_id step action date_processed next_state prev_state
---------- ------- ---- ------ ------------------- ---------- ----------
1 1 1 a 04/01/2002 05:35:00 2 NULL
1 2 2 rmi 04/01/2002 06:00:00 3 1
1 1 1 a 04/01/2002 06:15:00 2 NULL
1 2 2 a 04/01/2002 06:20:00 3 1
1 3 3 a 04/01/2002 06:35:00 NULL 2

The step goes back to 1 and then continues on so say step 7 requested more info ... after that would be step 1 then step 7 again and continue on. The did the rankings by date_processed and this works fine except for the part where there are groups of users in a single step. example:

project_id user_id step action date_processed next_state prev_state
---------- ------- ---- ------ ------------------- ---------- ----------
1 1 1 a 04/01/2002 05:35:00 2 NULL
1 2 2 a 04/01/2002 06:00:00 3 1
1 3 2 a 04/01/2002 06:15:00 3 1
1 4 3 a 04/01/2002 06:20:00 4 2
1 2 4 a 04/01/2002 06:35:00 NULL 3

Here is the query I'm working with right now.

select
(select count(*) + 1
from STARS.stars.dbo.tworkflow as wf
where wf.ckproject = tworkflow.ckproject
and wf.cdefault = 0
and wf.cdtprocessed < tworkflow.cdtnotified) as ranked_step,
tproject.ckproject as project_id,
users.user_id,
tworkflow.ckstate as workflow_step,
project_approval_actions.project_approval_action_id as action_id,
tworkflow.ccomments as comment,
tworkflow.cdtnotified as date_notified,
tworkflow.cdtprocessed as date_processed,
tworkflow.cdtcreate as date_created,
creator.user_id as creator,
tworkflow.cdtupdate as date_updated,
updator.user_id as updator
from STARS.stars.dbo.tproject as tproject
inner join STARS.stars.dbo.tworkflow as tworkflow on tproject.ckproject = tworkflow.ckproject
inner join users on tworkflow.cactor = users.user_name
inner join STARS.stars.dbo.taction as taction on tworkflow.ckaction = taction.ckaction
inner join project_approval_actions on taction.cname = project_approval_actions.name
left join users as creator on tworkflow.ccreateby = creator.user_name
left join users as updator on tworkflow.cupdateby = updator.user_name
where tproject.clstatus in (11, 12, 47, 56) -- the approved workflows
and tworkflow.cdefault = 0 -- only the actual workflows
order by tworkflow.cdtprocessed

This code can get as ugly as it wants since it will only run once to import all the workflows. After that it will not be used again. If you need more information or a more detailed table schema just let me know.

Thanks!

Onamuji
Aged Yak Warrior

504 Posts

Posted - 2002-04-01 : 10:08:49
One thing I may have forgotten .. here is some actual real data from the db... and how I would like it to look after the step fixing has been done.

Before:
ranking_step next_state prev_state project_id user_id step action date_notified date_processed
------------ ---------- ---------- ---------- ------- ---- ------ ------------- --------------
1 2 NULL 30272 1008 1 1 6/19/00 8:26 6/19/00 8:26
2 3 1 30272 10 2 3 6/19/00 11:33 6/19/00 11:33
3 2 NULL 30272 1008 1 1 6/19/00 14:35 6/19/00 14:35
4 3 1 30272 10 2 1 6/19/00 15:16 6/19/00 15:16
5 4 2 30272 942 3 1 7/25/00 9:23 7/25/00 9:23
6 8 3 30272 958 4 1 7/25/00 11:44 7/25/00 11:44
7 NULL 4 30272 942 8 1 7/28/00 10:03 7/28/00 10:03

After:
project_id user_id step action date_notified date_processed
---------- ------- ---- ------ ------------- --------------
30272 1008 1 1 6/19/00 8:26 6/19/00 8:26
30272 10 2 3 6/19/00 11:33 6/19/00 11:33
30272 1008 3 1 6/19/00 14:35 6/19/00 14:35
30272 10 4 1 6/19/00 15:16 6/19/00 15:16
30272 942 5 1 7/25/00 9:23 7/25/00 9:23
30272 958 6 1 7/25/00 11:44 7/25/00 11:44
30272 942 7 1 7/28/00 10:03 7/28/00 10:03

As you can see using the ranking method for this workflow would be fine ... just the ones that have multiple users in a step in it are giving me a headache...

For example. I believe this is the most complicated workflow there is in the system. Shows the headache I'm talking about really well.

Before:
ranked_step next_state prev_state project_id user_id step action date_processed
----------- ---------- ---------- ---------- ------- ---- ------ --------------
1 2 NULL 33932 1819 1 1 3/21/01 11:16
2 3 1 33932 1538 2 1 3/22/01 10:12
3 4 2 33932 3163 3 1 6/21/01 14:19
4 5 3 33932 1819 4 1 6/25/01 14:59
5 6 4 33932 1538 5 3 6/26/01 12:45
6 5 5 33932 1819 1 1 6/26/01 12:50
7 6 4 33932 1538 5 1 7/5/01 9:38
8 7 5 33932 826 6 1 7/9/01 11:22
9 8 6 33932 1445 7 1 7/9/01 11:27
10 9 7 33932 3234 8 1 7/10/01 7:23
11 9 7 33932 643 8 3 7/12/01 9:09
12 8 8 33932 1819 1 1 7/16/01 14:51
13 9 7 33932 3234 8 1 7/17/01 14:58
14 9 7 33932 643 8 1 7/17/01 22:23
15 10 8 33932 1406 9 1 7/19/01 14:41
16 11 9 33932 1659 10 1 7/20/01 10:00
17 12 10 33932 902 11 1 9/6/01 10:43
18 13 11 33932 1930 12 1 11/1/01 14:44
19 NULL 12 33932 1538 13 1 11/2/01 15:52

After:
project_id user_id step action date_processed
---------- ------- ---- ------ --------------
33932 1819 1 1 3/21/01 11:16
33932 1538 2 1 3/22/01 10:12
33932 3163 3 1 6/21/01 14:19
33932 1819 4 1 6/25/01 14:59
33932 1538 5 3 6/26/01 12:45
33932 1819 6 1 6/26/01 12:50
33932 1538 7 1 7/5/01 9:38
33932 826 8 1 7/9/01 11:22
33932 1445 9 1 7/9/01 11:27
33932 3234 10 1 7/10/01 7:23
33932 643 10 3 7/12/01 9:09
33932 1819 11 1 7/16/01 14:51
33932 3234 12 1 7/17/01 14:58
33932 643 12 1 7/17/01 22:23
33932 1406 13 1 7/19/01 14:41
33932 1659 14 1 7/20/01 10:00
33932 902 15 1 9/6/01 10:43
33932 1930 16 1 11/1/01 14:44
33932 1538 17 1 11/2/01 15:52


Edited by - onamuji on 04/01/2002 10:44:08
Go to Top of Page

Onamuji
Aged Yak Warrior

504 Posts

Posted - 2002-04-01 : 12:52:19
Changing the date_processed from that to date_notified (since date_notified each step's group is sent out at the same time i can use that to rank... just need to figure out how to do ranking without skipping numbers... like user a, b, c can all have rank 3 and i want user d to have rank 4 .... without being 6 ... any ideas?
(select count(*) + 1 from @workflows as wf where wf.date_notified < workflows.date_notified)
Go to Top of Page

Onamuji
Aged Yak Warrior

504 Posts

Posted - 2002-04-01 : 13:43:08
I feel bad posting these types of things and 80% of the time I end up answering my own posts! Well at least typing all these helps me think about the problem more...

Solved it by first writing a row based update, then changed it to this set based update. This just updates the data I import (the import does the ranking this just fixes the gaps).

update #workflows
set step = (select count(wf.c1) + 1
from (select distinct
step as c1
from #workflows as wf
where wf.project_id = #workflows.project_id) as wf
where wf.c1 < step)

Thanks for letting me use this place for brainstorming!
Go to Top of Page
   

- Advertisement -