Mark Davies Ответов: 1

Как поменять местами поля guid из 1 строки в другую в MS SQL ?


Ладно, я довольно новичок в SQL, так что, вероятно, я далеко отсюда, но вот что я хочу сделать. У меня есть tblFixtures, который содержит Guid игроков, которые были нарисованы, чтобы играть друг с другом в нокауте пула. tblFixtures имеет столбцы uniqueidentifier player1 и player2. Я уже добавил "Byes", потому что общее количество игроков, необходимых для такого нокаута, равно 8.. так, например, если в tblFixtures есть только 6 игроков, он добавляет 2 пустых игрока с Guid "00000000-0000-0000-0000-000000000000". Таким образом, 2 игрока получат "свободный проход в следующий раунд" ("пока"), но мне нужно переставить стол на случай, если "пока" окажется вничью против такого "пока".


Игрок 1 Игрок 2
{72462373-6B64-4427-9F9F-9A872261A333} v {9C90B324-78CA-4C7B-BC79-15537F3935B2}
{00000000-0000-0000-0000-000000000000} в {00000000-0000-0000-0000-000000000000}
{3E828BB1-AEC2-4543-BD26-E12AD886D2E8} v {72462373-6B64-4427-9F9F-9A872261ABC2}
{4F9C3964-2672-4413-8A01-2ED09CA7A711} v {AFEB20EB-5CCB-4302-A999-CC772F8ABACE}
Мне нужно, чтобы он поместил пустой Guid в любом месте против такого GUID игрока, как этот..


Игрок 1 Игрок 2
{72462373-6B64-4427-9F9F-9A872261A333} v {9C90B324-78CA-4C7B-BC79-15537F3935B2}
{3E828BB1-AEC2-4543-BD26-E12AD886D2E8} в {00000000-0000-0000-0000-000000000000}
{00000000-0000-0000-0000-000000000000} v {72462373-6B64-4427-9F9F-9A872261ABC2}
{4F9C3964-2672-4413-8A01-2ED09CA7A711} v {AFEB20EB-5CCB-4302-A999-CC772F8ABACE}

Приведенный ниже код требует СВЕРХКОМАНДЫ и нескольких настроек, я думаю, но это все, что я мог получить. То, что я пытаюсь сделать, - это проверить, сколько игроков (включая BYES) есть, так что в этом случае есть 8, и это хранится в @matches. Теперь я хочу, чтобы он проверял строку за раз, используя цикл, равный сумме, хранящейся в @matches.. Эта проверка выглядит пустой 0-это идентификатор GUID, играя пустой 0 GUID-идентификатора. Если он будет найден, то он заменит Player1 в этой строке на следующий none blank player1 Guid, который он найдет, и обнулит его вместо этого.

Я просто еще не знаю, что понимаю, и не уверен, что остальная часть кода действительно будет работать, или кто-нибудь знает более простой способ сделать это?

Любая помощь будет оценена по достоинству. Вот что у меня есть на данный момент..

Объявить @matchess int
Выберите @matches = COUNT(accountID) из tblFixtures)*

Объявить @cnt INT = 0

Что я уже пробовал:

SELECT player1, ROW_NUMBER() OVER (ORDER BY player1) AS RowNumber
FROM   tblFixtures


DECLARE @Players int
SELECT @Players = COUNT(accountID) from tblEntrants WHERE paid='y'

DECLARE @cnt INT = 0

WHILE @cnt < @Players
    BEGIN

    If (SELECT Player1 WHERE ROW_NUMBER()  OVER (ORDER BY Player1) FROM tblFixtures)=@cnt = '00000000-0000-0000-0000-000000000000' AND SELECT(player1 WHERE ROW_NUMBER()  OVER (ORDER BY Player1 FROM tblFixtures)= @cnt) ='00000000-0000-0000-0000-000000000000' THEN
        BEGIN
            UPDATE tblFixtures SET Player1 = SELECT(TOP(1) player1  WHERE player1 <> '00000000-0000-0000-0000-000000000000' AND ROW_NUMBER()  OVER (ORDER BY Player1) FROM tblFixtures>@cnt) WHERE ROW_NUMBERr()  OVER (ORDER BY Player1) FROM tblFixtures=@cnt
            UPDATE tblFixtures SET Player1 = '0000-0000-0000-0000' WHERE SELECT(Top(1) player1) <> '00000000-0000-0000-0000-000000000000' AND ROW_NUMBER() FROM tblFixtures>@cnt 
        END
    SET @cnt = @cnt + 1
END

1 Ответов

Рейтинг:
0

Richard Deeming

Что-то вроде этого должно сработать:

-- Count the number of real players:
DECLARE @EntrantCount int;

SELECT
    @EntrantCount = Count(1)
FROM
    tblEntrants
WHERE
    paid = 'y'
;


-- Find the next highest power of 2 - the total number of players required:
DECLARE @PlayerCount int = POWER(2, CEILING(LOG(@EntrantCount, 2)));


-- Generate a random order for all entrants and byes:
DECLARE @AllPlayers TABLE 
(
    RN int NOT NULL Primary Key, 
    ID uniqueidentifier NULL
);

WITH ctePlayers As
(
    SELECT
        ID
    FROM
        tblEntrants
    WHERE
        paid = 'y'

    UNION ALL

    SELECT TOP (@PlayerCount - @EntrantCount)
        Null
    FROM
        sys.objects
),
cteOrderedPlayers As
(
    SELECT
        ROW_NUMBER() OVER (ORDER BY NewID()) As RN,
        ID
    FROM
        ctePlayers
)
INSERT INTO @AllPlayers
(
    RN,
    ID
)
SELECT
    RN,
    ID
FROM
    cteOrderedPlayers
;


-- Build the random fixtures:
DECLARE @Fixtures TABLE 
(
    RN int NOT NULL IDENTITY(1, 1) Primary Key, 
    Player1 uniqueidentifier NULL, 
    Player2 uniqueidentifier NULL
);

WITH cteFixtures As
(
    SELECT
        P1.ID As Player1,
        P2.ID As Player2
    FROM
        @AllPlayers As P1
        LEFT JOIN @AllPlayers As P2
        ON P2.RN = P1.RN + 1
    WHERE
        -- Only take the odd-numbered rows for player 1:
        (P1.RN & 1) = 1
)
INSERT INTO @Fixtures
(
    Player1,
    Player2
)
SELECT
    Player1,
    Player2
FROM
    cteFixtures
;


-- Resolve "bye-bye" rows:
WHILE Exists(SELECT 1 FROM @Fixtures WHERE Player1 Is Null And Player2 Is Null)
BEGIN
    DECLARE @R1 int, @R2 int, @ID uniqueidentifier;

    -- Find the first row without a player:
    SELECT TOP 1 
        @R1 = RN 
    FROM 
        @Fixtures 
    WHERE 
        Player1 Is Null 
    And 
        Player2 Is Null
    ;

    -- Find the first row with a player on both sides:
    SELECT TOP 1
        @R2 = RN,
        @ID = Player1
    FROM
        @Fixtures
    WHERE
        Player1 Is Not Null
    And
        Player2 Is Not Null
    ;

    IF @@ROWCOUNT = 0
    BEGIN
        -- Just in case, to avoid an infinite loop, although I'm 99.9% sure this will never happen:
        RAISERROR('No way to resolve - should never happen.', 16, 1);
    END;

    -- Swap player 1:
    UPDATE
        @Fixtures
    SET
        Player1 = CASE RN
            WHEN @R1 THEN @ID
            ELSE Null
        END
    WHERE
        RN In (@R1, @R2)
    ;
END;


-- Finished:
INSERT INTO tblFixtures
(
    Player1,
    Player2
)
SELECT
    IsNull(Player1, '00000000-0000-0000-0000-000000000000'),
    IsNull(Player2, '00000000-0000-0000-0000-000000000000')
FROM
    @Fixtures
;