开发者

Is this SQL Query possible?

Suppose I have this data:

Employee  Task   IsCurrent
--------  ----   ---------
Jeff      1      Yes
Jeff      2      No
Jane      1      No
Jane      2      Yes
Jane      3      No
Jane      4      No
Jake      1      Yes

Employees have some number of tasks, and one of them will be current. The task number indicates an ordering -- they perform tasks in order, looping back to the beginning when they're done with the last one. I'd like a query to see the next three tasks. I'd like this result set:

Employee    CurrentTask  NextTask  NextTask2
--------    ----开发者_JAVA技巧-------  --------  ---------
Jeff        1            2         1
Jane        2            3         4
Jake        1            1         1

Is this possible? I'm using SQL 2005

UPDATE: Sorry, I didn't make clear that the task numbers aren't necessarily sequental -- i.e. Mike might actually have tasks 10, 23, and 223. So I can't just join looking for the next sequential task number.


Use:

WITH summary AS (
   SELECT t.employee,
          t.task,
          t.iscurrent,
          ROW_NUMBER() OVER (PARTITION BY t.employee
                                 ORDER BY t.task) AS rank
     FROM TABLE t)
   SELECT a.employee,
          a.task AS current_task,
          COALESCE(b.task, y.min_task) AS next_task,
          COALESCE(c.task, y.min_task) AS next_task2
     FROM summary a
     JOIN (SELECT x.employee,
                  MIN(x.task) AS min_task
             FROM TABLE x
         GROUP BY x.employee) y ON y.employee = a.employee
LEFT JOIN summary b ON b.employee = a.employee
                   AND b.rank = a.rank + 1
LEFT JOIN summary c ON c.employee = a.employee
                   AND c.rank = a.rank + 2                   
    WHERE a.iscurrent = 'yes'

Like I said earlier, would be easier if SQL Server supported LEAD/LAG functions...


If you are only interested in the next and the one after that, you can use the following:

SELECT t.employee,
       t.task AS current_task,
       t1.task AS next_task, 
       t2.task AS next_task_2
FROM tasks t
  LEFT JOIN tasks t1 ON t1.task = t.task + 1 AND t1.employee = t.employee
  LEFT JOIN tasks t2 ON t2.task = t1.task + 1 AND t2.employee = t1.employee
WHERE t.isCurrent = 'yes'


Shouldn't be too bad a stored proc with the following steps

Create a temp table with the columns Employee, CurrentTask, NextTask, and NextTask2 Insert records with each employee and their CurrentTask. This is a simple SQL statement... and you could combine steps 1 and 2.

INSERT INTO #tempTable (Employee, CurrentTask) VALUES Employee, Task WHERE IsCurrent = 'Yes'

Then You'll need to loop through these records, progressively updating the NextTask and NextTask2 columns using a combination of TOP 1 and Order By Task ASC


Maybe not the best, but you can try this way, asuming there is no more than 2 NextTask's ;)

SELECT e.Employee, e.Task AS CurrentTask, 
(
    SELECT TOP 1 e1.Task FROM dbo.Employees AS e1 WHERE e1.Employee=e.Employee AND e1.Task > e.Task ORDER BY e1.Task ASC
) AS NextTask,
(
    SELECT TOP 1 e2.Task FROM dbo.Employees AS e2 WHERE e2.Employee=e.Employee AND e2.Task > (
        SELECT TOP 1 e1.Task FROM dbo.Employees AS e1 WHERE e1.Employee=e.Employee AND e1.Task > e.Task ORDER BY e1.Task ASC
    ) ORDER BY e2.Task ASC
) AS NextTask2
FROM dbo.Employees AS e
WHERE e.IsCurrent = 'Yes'

PS. maybe PIVOT would do the trick, but im not to good at it.


This is a two-part problem. First, you have to solve the modulus problem (listing tasks in order, starting with the current task):

Step 1: build a query whose results look like this (I've altered the data as per your edit)

Employee  IsCurrent OriginalTask [Task+MaxTask] as Task
--------  ----      ------------ ---------------------- 
Jeff      Yes       37           15
Jeff      No        44           22
Jane      No        55           13
Jane      Yes       67           25
Jane      No        73           31
Jane      No        84           42
Jake      Yes       38           19

Step 2: do a UNION with the original query

Employee  IsCurrent Task OriginalTask
--------  ----      ---- ------------
Jeff      Yes       15   15
Jeff      No        22   22
Jeff      Yes       37   15
Jeff      No        44   22
Jane      No        13   13
Jane      Yes       25   25
Jane      No        31   31
Jane      No        42   42
Jane      No        55   13
Jane      Yes       67   25
Jane      No        73   31
Jane      No        84   42
Jake      Yes       19   19
Jake      Yes       38   19

Step 3: Suppress rows where task# < lowest current or task# >= highest current

Employee  IsCurrent Task OriginalTask
--------  ----      ---- ------------ 
Jeff      Yes       15   15
Jeff      No        22   22
Jane      Yes       25   25
Jane      No        31   31
Jane      No        42   42
Jane      No        55   13
Jake      Yes       19   19

Now you have the modulus data, and an ordinary pivot-problem.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜