Как расширить набор данных, чтобы при использовании CTE было только 1 SeatNum на строку? - PullRequest
0 голосов
/ 05 октября 2019

This is the input

This is the required output

Вот что я пробовал. Проблема с приведенным ниже подходом заключается в том, что функция ROW_NUMBER () сбрасывает SeatNum в 1 для каждой отдельной строки.

Любая помощь приветствуется. Другой подход, который я попробовал, был с функциями RANK и DENSE_RANK, но они также сбрасывали значение SeatNum на 1 после выполнения кода.

CREATE TABLE Seating (
    Section INT,
    Row INT,
    SeatNum INT,
    NumOfSeats INT,
    LastSeat INT);

INSERT INTO Seating(Section,Row,SeatNum,NumOfSeats,LastSeat)
VALUES(101,1,1,2,2),
      (101,1,3,4,6),
      (102,4,5,2,6),
      (102,5,1,2,2),
      (103,1,6,2,7);

WITH cte
AS
(  SELECT 
    Section,
    Row,
    SeatNum,
    NumOfSeats,
    LastSeat
    FROM Seating 

    UNION ALL

    SELECT 
    Section,
    Row,
    SeatNum,
    NumOfSeats,
    LastSeat
    FROM Seating
    WHERE Section = 101 

    UNION ALL

    SELECT 
    Section,
    Row,
    SeatNum,
    NumOfSeats,
    LastSeat
    FROM Seating
    )

SELECT 
Section,
Row,
ROW_NUMBER() OVER (PARTITION BY Section,Row ORDER BY Row) AS SeatNum,
NumOfSeats,
LastSeat from cte

ORDER BY Section;

Ответы [ 3 ]

1 голос
/ 05 октября 2019

Я думаю, что такие проблемы - хорошая возможность узнать о рекурсивных CTE :

with cte as (
      select Section, Row, SeatNum, NumOfSeats, LastSeat, 1 as n
      from seating
      union all
      select Section, Row, SeatNum + 1, NumOfSeats, LastSeat, n + 1
      from cte
      where n < NumOfSeats
     )
select Section, Row, SeatNum, NumOfSeats, LastSeat
from cte
order by Section, Row, SeatNum, NumOfSeats, LastSeat;

Одно ограничение состоит в том, что по умолчанию количество шагов рекурсии равно 100- но я сомневаюсь, что в любой секции по 100 мест подряд, так что это не проблема. Значение по умолчанию может быть расширено с помощью OPTION (MAXRECURSION 0).

Здесь - это db <> скрипка.

0 голосов
/ 05 октября 2019

Вы должны использовать таблицу Tally и CROSS APPLY для расширения каждой строки:

;WITH Tally (N) AS
(

    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
    FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
    CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)

) 
SELECT Section, [Row], t2.SN SeatNumber,NumOfSeats, LastSeat 
FROM  SEATING
    CROSS APPLY  (SELECT TOP(NumOfSeats) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) + (SeatNum - 1) SN FROM Tally) t2
0 голосов
/ 05 октября 2019

Вы можете создать функцию табличного значения, как показано ниже, и использовать перекрестное применение для получения желаемого результата

CREATE FUNCTION GetSeats
(   
    @From int,
    @To int
)
RETURNS  @GetSeats TABLE (Seat int)
AS
begin 
    declare @currnetCount int = @From;
    while(@currnetCount <= @To) begin
        insert into @GetSeats values (@currnetCount);
        SET @currnetCount = @currnetCount + 1;
    end;

    return;
END
GO

ВЫБРАТЬ ЗАЯВЛЕНИЕ

SELECT        s.Section, s.Row, se.Seat SeatNum, NumOfSeats, LastSeat
FROM            Seating AS s
CROSS APPLY GetSeats(s.SeatNum, s.LastSeat) se
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...