2014-02-20 3 views
1

Я, наверное, подумал об этом. У меня есть простая таблица с колонками Name и Ticket Quantity. Я хочу вывести список строк по ряду имен для каждого купленного количества. См. Пример ниже.Линии списков за единицу

Таблица:

Name   Quantity 
----------------------- 
Bob   1 
Joe   2 
Sally   1 

Выход:

Bob 
Joe 
Joe 
Sally 

Как я могу добиться этого в TSQL?

+0

присоединиться к таблице номеров. –

+0

Я чувствую запах рекурсивного CTE – SQLMason

+1

@DanAndrews - [Рекурсивные CTE медленно] (http://stackoverflow.com/questions/10819/sql-auxiliary-table-of-numbers/2663232#2663232). Создание таблицы постоянных номеров и 'SELECT Name FROM Names JOIN Numbers ON Number <= Quantity' было бы лучше. –

ответ

2

SETUP:

DECLARE @table TABLE (
    NAME VARCHAR(10), 
    Quantity INT 
    ) 

INSERT INTO @table 
SELECT 'Bob', 1 UNION ALL 
SELECT 'Joe', 2 UNION ALL 
SELECT 'Sally', 1 

Рекурсивный CTE

;WITH Members (
    NAME, 
    Quantity 
    ) 
AS (
    -- Base case 
    SELECT NAME, 
     Quantity 
    FROM @table 

    UNION ALL 

    -- Recursive 
    SELECT NAME, 
     Members.Quantity - 1 
    FROM Members 
    WHERE Members.Quantity > 1 
    ) 
SELECT NAME 
FROM Members 
OPTION (MAXRECURSION 0) 
ORDER BY 1 

Результат:

Bob 
Joe 
Joe 
Sally 

В качестве альтернативы вы могли бы (по предложению @Martin Смита):

DECLARE @numbers TABLE (number INT) 

INSERT INTO @numbers (number) 
VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10) 

Наконец:

SELECT NAME 
FROM @table t 
INNER JOIN @numbers n ON n.number <= t.Quantity 
ORDER BY 1 

Результат:

Bob 
Joe 
Joe 
Sally 


И если вы действительно любите рекурсивный CTE (becau они хорошо пахнут), вы можете построить таблицу чисел с рекурсивным CTE. Вы должны использовать физические таблицы, а не таблицы переменных, как вы видите здесь, так что вам не нужно создавать их каждый раз.

;WITH Numbers (Value) 
AS (
    -- Base case 
    SELECT 32767 Value 

    UNION ALL 

    -- Recursive 
    SELECT Numbers.Value - 1 
    FROM Numbers 
    WHERE Numbers.Value > 1 
    ) 
INSERT INTO @numbers (number) 
SELECT Value 
FROM Numbers 
OPTION (MAXRECURSION 32767) 
+0

Но, конечно, рекурсия. Благодаря! – user3333387

Смежные вопросы