Возможен ли этот SQL-запрос? - PullRequest
       17

Возможен ли этот SQL-запрос?

1 голос
/ 03 сентября 2010

Предположим, у меня есть эти данные:

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 ]

5 голосов
/ 03 сентября 2010

Использование:

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 голос
/ 03 сентября 2010

Если вас интересует только следующий и следующий за ним, вы можете использовать следующее:

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'
0 голосов
/ 03 сентября 2010

Это проблема из двух частей.Во-первых, вы должны решить проблему с модулем (перечисление задач по порядку, начиная с текущей задачи):

Шаг 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

Теперь у вас есть данные о модуле и обычная проблема с опорой.

0 голосов
/ 03 сентября 2010

Не должно быть слишком плохим хранимым процессом со следующими шагами

Создать временную таблицу со столбцами Employee, CurrentTask, NextTask и NextTask2 Вставить записи с каждым сотрудником и его CurrentTask.Это простой оператор SQL ... и вы можете объединить шаги 1 и 2.

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

Затем вам нужно будет выполнить цикл по этим записям, постепенно обновляя столбцы NextTask и NextTask2, используя комбинацию TOP 1 и Order By Task ASC

0 голосов
/ 03 сентября 2010

Может быть, не самый лучший, но вы можете попробовать этот способ, если предположить, что не более 2 NextTask;)

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 справится с задачей, но я не очень хорош в этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...