SQL Server query help with pulling rows out of tangled mess of a table layout
This might be long and I apologize up front, I can get "wordy" trying to explain myself. Haven't learned to be as concise as I should be.
My issue is that I'm held back by my lack of experience and what I believe is a poorly laid out table. I'm needing to pull certain columns out of a table and report on date differences embedded in one of the elements. (See sample below).
I cannot reorganize the table as it's part of an application that my company is using on a help desk , so I'm stuck with how it's "organized".
The structure of the table is essentially this: all column types are varchar() of different lengths, the database is SQL Server 2005 on Wind开发者_如何学Pythonows Server 2003.
tickID | tickGen | tickAudit
----------------------------------
124567 | 1 | 2011-07-22 08:00:00 joeuser Open Ticket
124567 | 2 | 2011-07-22 08:00:00 joeuser Open Ticket Not Assigned
124567 | 3 | 2011-07-22 08:00:00 joeuser Open Ticket Priority Urgent
124567 | 4 | 2011-07-22 09:00:00 freduser Open Ticket Add Assignee
Management wants to know the time difference between these to "time stamps" from the tickAudit column from when "joeuser" made the ticket "not assigned" and when "freduser" added an assignee to the ticket.
In this example I came up with these queries which "sort of works" but I believe could be better:
declare @startTime datetime
declare @endTime datetime
declare @mrid varchar(6)
set @mrid = '124567'
select @startTime = cast(substring(tickAudit,1,19) as datetime)
from tickHistory where tickID = @tickID and tickAudit like '%Not Assigned'
select @endTime = cast(substring(tickAudit,1,19) as datetime)
from tickHistory where tickID = @tickID and tickAudit like '%Add Assignee'
select @mrid as 'ticket', @startTime as 'startTime',
@endTime as 'endTime', datediff(mi,@startTime,@endTime) as 'diff'
The query however cannot handle an issue where a "ticket" has multiple entries where it was assigned and then not assigned as in this example:
tickID | tickGen | tickAudit
----------------------------------
124568 | 1 | 2011-07-22 08:00:00 joeuser Open Ticket
124568 | 2 | 2011-07-22 08:00:00 joeuser Open Ticket Not Assigned
124568 | 3 | 2011-07-22 08:00:00 joeuser Open Ticket Priority Urgent
124568 | 4 | 2011-07-22 09:00:00 freduser Open Ticket Add Assignee
124568 | 5 | 2011-07-22 11:00:00 freduser Open Ticket Not Assigned
124568 | 6 | 2011-07-22 12:00:00 bobuser Open Ticket Priority Low
124568 | 7 | 2011-07-22 12:00:00 bobuser Open Ticket Add Assignee
Here the "freduser" has edited the ticket and now it is "not assigned" again and two hours later "bobuser" has edit it and assigned the ticket. So there are 2 time stamps that I need to report on. My query will only return the difference of tickGen #5 and tickGen #7. It ignores the difference of tickGen #2 and tickGen #4 as well.. or as I suspect it's only displaying the last of the valid matches to the query regardless how many is returned.
And this is where I get stuck. Hopefully someone can give me some suggestions or an example to account for situations in the above example.
Here is one way to do it:
with th (tickID,tickGen,tickTime,tickType)
as
(select tickID,tickGen,
cast(substring(tickAudit,1,19) as datetime) as tickTime,
RIGHT(tickAudit,12)
from tickHistory
where RIGHT(tickAudit,12) in ('Not Assigned','Add Assignee'))
select t1.tickID,
t1.tickTime startTime,
t2.tickTime endTime,
DATEDIFF(mi,t1.tickTime,t2.tickTime) as diff
from th as t1
inner join th as t2
on t1.tickID = t2.tickID
and t1.tickGen < t2.tickGen
where t1.tickType = 'Not Assigned'
and t2.tickType = 'Add Assignee'
and t2.tickGen = (select MIN(tickGen) from th
where th.tickID = t1.tickID
and th.tickGen > t1.tickGen)
精彩评论