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 2005 Forums
 Transact-SQL (2005)
 Equal Distribution Problem

Author  Topic 

de4ever@gmail.com
Starting Member

36 Posts

Posted - 2009-10-27 : 08:54:39
Hi All,

I have an OPD patient table as below

visitID hospitalID PatientID visitingDate
1 1 1 2009-10-27 17:47:59.860
2 2 2 2009-10-27 17:47:59.000
3 3 3 2009-10-27 17:47:59.000
4 1 4 2009-10-27 17:47:59.000

I need to allocate patients to hospitals .But I need to distribute patients eqaully to all the hospital in round robin fashion.So I am in search of a procedure which will always give me the hospital ID where new patient can be allocated.Like in this case..
HopitalID :2


Waiting for your cooperation

Thanks

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2009-10-27 : 09:50:49
[code]
select (hospitalID + 1) % 4 + 1
from
(
select hospitalID, row_no = row_number() over (order by visitID desc)
from OPD
) a
where row_no = 1
[/code]


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

mfemenel
Professor Frink

1421 Posts

Posted - 2009-10-27 : 10:00:53
here's a quick example. basically what you want to look for is the hospital id with the lowest count in your table. The code below gives you the right answer but you don't want to have to recount your entire visit history every time you make a decision on where to assign a patient so you'll need to fine tune your where clause a bit or you'll have some perf problems when you're counting a million records.

Create table #test(visitID tinyint, hospitalid tinyint, patientid tinyint, visitingdate datetime default getdate())
insert into #test values(1,1,1,getdate())
waitfor delay '00:00:03'
insert into #test values(2,2,2,getdate())


Create table #hospitals (hospitalid tinyint, hospitalname varchar(30))
insert into #hospitals
select 1,'Test1'
UNION
select 2, 'Test2'
UNION
select 3,'Test3'
UNION
select 4, 'Test4'

select top 1 h.hospitalid,count(t.hospitalid) over( partition by t.hospitalid) as Visits
from #hospitals h
left join #test t
on h.hospitalid=t.hospitalid
GROUP BY h.hospitalid,t.hospitalid
ORDER BY COUNT(*) ASC

Mike
"oh, that monkey is going to pay"
Go to Top of Page

mfemenel
Professor Frink

1421 Posts

Posted - 2009-10-27 : 10:17:44
I was just looking at khtan's post above mine and I think it brings up an interesting point. I find myself telling developers not to program themselves into a corner because what you design today won't be the same as what you're using a year from now. While my solution probably will get picked apart and has room for improvement I see some things that raise red flags in the solution above it. First, don't assume you'll always have 4 hospitals. Every time you add a hospital your %4 statement needs to be updated and when you're not around 2 years from now who will remember to do that because we know documentation is always scarce. Second when you add a new hospital it's not going to be in the OPD table so it's never going to get picked up into your circulation. So you'll enjoy some quality time figuring that out before you realize no one has ever been assigned to that new hospital and so it's not in your rotation. Finally you should probably consider having an active flag (as a bit please!) on your hospitals table so that if a hospital gets shut down, or sold, or is unavailable for visitis, you have a way of dropping it out of the logic either permanently or temporarily.
My point here is not to be critical but make sure you put some forethought into how your query is going to live and breathe through it's lifecycle. Hope that helps. Sorry khtan for using your solution as an example. I've just been seeing a lot of this type of thing at work lately and this post made a good spot to point out the issue.

Mike
"oh, that monkey is going to pay"
Go to Top of Page

de4ever@gmail.com
Starting Member

36 Posts

Posted - 2009-10-28 : 00:26:21
Hi
Thanks for your reply.I think the correct ouput should be hospitalID 3 as HospitalID 1 and 2 has already been allotted for patient.So next turn should be hospital ID 3.If I am wrong please correct me.

quote:
Originally posted by mfemenel

here's a quick example. basically what you want to look for is the hospital id with the lowest count in your table. The code below gives you the right answer but you don't want to have to recount your entire visit history every time you make a decision on where to assign a patient so you'll need to fine tune your where clause a bit or you'll have some perf problems when you're counting a million records.

Create table #test(visitID tinyint, hospitalid tinyint, patientid tinyint, visitingdate datetime default getdate())
insert into #test values(1,1,1,getdate())
waitfor delay '00:00:03'
insert into #test values(2,2,2,getdate())


Create table #hospitals (hospitalid tinyint, hospitalname varchar(30))
insert into #hospitals
select 1,'Test1'
UNION
select 2, 'Test2'
UNION
select 3,'Test3'
UNION
select 4, 'Test4'

select top 1 h.hospitalid,count(t.hospitalid) over( partition by t.hospitalid) as Visits
from #hospitals h
left join #test t
on h.hospitalid=t.hospitalid
GROUP BY h.hospitalid,t.hospitalid
ORDER BY COUNT(*) ASC

Mike
"oh, that monkey is going to pay"




Go to Top of Page

de4ever@gmail.com
Starting Member

36 Posts

Posted - 2009-10-28 : 00:51:20
Hi khtan,

I am not getting why you are ordering by visitID .Your query is returning me multiple rows.Can you please explain..

Thanks

quote:
Originally posted by khtan


select (hospitalID + 1) % 4 + 1
from
(
select hospitalID, row_no = row_number() over (order by visitID desc)
from OPD
) a



KH
[spoiler]Time is always against us[/spoiler]



Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2009-10-28 : 06:15:16
Edited the original post.


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page
   

- Advertisement -