Сложный вопрос по прогнозированию следующих записей - PullRequest
1 голос
/ 23 июня 2009

Я делаю сценарий тестирования

6 человек на каждом сайте

Site 1 - A, B, C, D, E, F
Site 2 - G, H, I, J, K, L
Site 3 - M, N, O, P, Q, R
Site 4 - S, T, U, V, W, X

Я хочу написать запрос, который может предложить мне по дате людей, которые могут проверить сайт - по два за раз. Вот правила:

Правило 1: Если человек проверял свой сайт в 1-й день, то его ход должен приходить на 4-й день, а не раньше - ПРИМЕНИМО ТОЛЬКО НА ТЕКУЩУЮ НЕДЕЛЮ. Таким образом, если A и D протестируют сайт 22-го, B и E - 23-го, а C и F - 24-го, то за эту неделю A и D могут протестировать сайт только 25-го. Воскресенье - праздник

Правило 2: Каждую неделю пара должна меняться. Правило 1 все еще применимо к новой паре.

Правило 3: Лицо, принадлежащее к определенному сайту, не может проверять другие сайты.

В запросе я должен быть в состоянии позже поменяю пару из 2 человек и сделать их по 3 человека за раз или увеличить количество людей на каждом сайте с 6 до 10, с несколько изменений в коде.

ОБРАЗЦЫ ДАННЫХ

DECLARE @Site TABLE
(
SiteID int,
SiteNm varchar(10)
)

DECLARE @Person TABLE
(
PersonID int,
PersonName char(1),
SiteID int
)

INSERT @Site
SELECT 1, 'Site1' UNION ALL
SELECT 2, 'Site2' UNION ALL
SELECT 3, 'Site3' UNION ALL
SELECT 4, 'Site4' 

INSERT @Person
SELECT 1, 'A', 1 UNION ALL
SELECT 2, 'B', 1 UNION ALL
SELECT 3, 'C', 1 UNION ALL
SELECT 4, 'D', 1 UNION ALL
SELECT 5, 'E', 1 UNION ALL
SELECT 6, 'F', 1 UNION ALL
SELECT 7, 'G', 2 UNION ALL
SELECT 8, 'H', 2 UNION ALL
SELECT 9, 'I', 2 UNION ALL
SELECT 10, 'J', 2 UNION ALL
SELECT 11, 'K', 2 UNION ALL
SELECT 12, 'L', 2 UNION ALL
SELECT 13, 'M', 3 UNION ALL
SELECT 14, 'N', 3 UNION ALL
SELECT 15, 'O', 3 UNION ALL
SELECT 16, 'P', 3 UNION ALL
SELECT 17, 'Q', 3 UNION ALL
SELECT 18, 'R', 3 UNION ALL
SELECT 19, 'S', 4 UNION ALL
SELECT 20, 'T', 4 UNION ALL
SELECT 21, 'U', 4 UNION ALL
SELECT 22, 'V', 4 UNION ALL
SELECT 23, 'W', 4 UNION ALL
SELECT 24, 'X', 4

Вот как я хочу вывод:

Date    Site 1    Site 2     Site 3     Site 4
22Jun    A,D        H,I       N,R        T,W
23Jun    B,E        J,K       M,P        V,X
...
26Jun    A,D         H,I       N,R        T,W  
...
29Jun    F,A         K,L       R,Q        W,U

и т. Д.

Можете ли вы помочь мне с запросом?

В запросе я должен быть в состоянии позже поменяю пару из 2 человек и сделать их по 3 человека за раз или увеличить количество людей на каждом сайте с 6 до 10, с несколько изменений в коде. Я хочу эту гибкость

Ответы [ 3 ]

2 голосов
/ 23 июня 2009
WITH    sets AS
        (
        SELECT  SiteID, SUBSTRING(CAST(PersonID AS VARCHAR(MAX)) + SPACE(8), 1, 8)AS result, 1 AS rn
        FROM    @Person p
        UNION ALL
        SELECT  p2.SiteID, s.result + SUBSTRING(CAST(PersonID AS VARCHAR(MAX)) + SPACE(8), 1, 8), rn + 1
        FROM    sets s
        JOIN    @Person p2
        ON      p2.siteid = s.siteid
                AND PATINDEX('%' + SUBSTRING(CAST(PersonID AS VARCHAR(MAX)) + SPACE(8), 1, 8) + '%', s.result) = 0
        ),
        cal AS
        (
        SELECT  1 AS rn
        UNION ALL
        SELECT  rn + 1
        FROM    cal
        WHERE   rn < 99
        ),
        pairs AS
        (
        SELECT  SiteId, result, ROW_NUMBER() OVER (PARTITION BY siteid ORDER BY rn2 % 30) pn
        FROM    (
                SELECT  s.*,
                        ROW_NUMBER() OVER (PARTITION BY siteid ORDER BY siteid) AS rn2
                FROM    sets s
                WHERE   rn = 6
                ) q
        WHERE   rn2 % 2 > 0
                AND rn2 % 12 > 5
                AND rn2 % 240 > 119
        )
SELECT  CAST('2009-01-01' AS DATETIME) + rn, siteid,
        SUBSTRING(result, 1 + (rn % 3) * 16, 8) AS first,
        SUBSTRING(result, 1 + (rn % 3) * 16 + 8, 8) AS second
FROM    cal
JOIN    pairs
ON      pn = (rn / 7 + 1)
        AND DATEPART(weekday, CAST('2009-01-01' AS DATETIME) + rn) <> 1
1 голос
/ 23 июня 2009

Это не то, что SQL предназначен для обработки. Я бы ОПРЕДЕЛЕННО переместил такую ​​алгоритмическую логику в код.

Если по какой-то причине вы не можете переместить его в код и абсолютно обязаны получать прогнозную информацию из базы данных, я бы рассмотрел сборку CLR в SqlSever, если вы используете MS SQL Server 2005 или 2008.

Справка из MSDN о том, как использовать CLR в SQL

0 голосов
/ 23 июня 2009

Технически возможно достичь этого в T-SQL с помощью вложенных циклов и встроенных запросов.

--loop over sites
    --loop over n-day periods (initially n=3, so day1->day4, discounting sundays)
        -- loop over pairs in that period
            --match people who are n+x IDs apart, x increments each n-day loop,
               --need to mod this against count(persons per site)
        -- end pairs loop
    -- end n-day loop
-- end sites loop

Все ужасно в T-SQL. Гораздо проще сделать это на языке более общего назначения.

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