这个SQL查询可能吗?

时间:2010-09-03 17:40:51

标签: sql sql-server sql-server-2005 tsql pivot

假设我有这些数据:

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

员工有一些任务,其中一个是最新的。任务编号表示一个排序 - 他们按顺序执行任务,当他们完成最后一个任务时循环回到开头。我想查询以查看接下来的三个任务。我想要这个结果集:

Employee    CurrentTask  NextTask  NextTask2
--------    -----------  --------  ---------
Jeff        1            2         1
Jane        2            3         4
Jake        1            1         1

这可能吗?我正在使用SQL 2005

更新:对不起,我没有说明任务编号不一定是后续的 - 也就是说迈克可能实际上有任务10,23和223.所以我不能只是加入寻找下一个顺序任务号。

5 个答案:

答案 0 :(得分:5)

使用:

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'

就像我之前所说的,如果SQL Server支持LEAD / LAG功能会更容易......

答案 1 :(得分:1)

如果您只对下一个和之后的一个感兴趣,可以使用以下内容:

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'

答案 2 :(得分:0)

也许不是最好的,但你可以尝试这种方式,假设下一个任务不超过2个;)

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。也许PIVOT可以做到这一点,但我不擅长它。

答案 3 :(得分:0)

使用以下步骤存储过程不应该太糟糕

使用Employee,CurrentTask,NextTask和NextTask2列创建临时表 插入每个员工及其CurrentTask的记录。 这是一个简单的SQL语句......您可以将步骤1和2结合起来。

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

然后,您需要遍历这些记录,使用TOP 1Order By Task ASC

的组合逐步更新NextTask和NextTask2列

答案 4 :(得分:0)

这是一个由两部分组成的问题。首先,您必须解决模数问题(按顺序列出任务,从当前任务开始):

第1步:构建一个结果如下所示的查询(我根据您的编辑修改了数据)

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

步骤2:使用原始查询执行UNION

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

步骤3:禁止任务#<最低电流或任务#> =最高电流

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

现在您拥有模数据和普通的枢轴问题。