2012-06-13 7 views
3

Моих данных выглядят следующим образомВставьте ряд, основанный на полях дорожит

Supplier Qty 
-------- --- 
ABC  3 
BCD  1 
CDE  2 
DEF  1 

я ожидаю, чтобы результат:

Supplier Qty 
-------- --- 
ABC  3 }---> Add additional row based on the number of qty 
ABC  3 } 
ABC  3 } 
BCD  1 
CDE  2 }---> Add additional row here too 
CDE  2 } 
DEF  1 

Ищет SQL SELECT заявление, которое выполняет ожидаемый результат.
Я использую Sql Server 2008

+0

есть максимум в QTY, что разрешено или могло быть любое число? – xQbert

+0

+1 для интересующего вопроса – whytheq

+1

Вы вставляете в ту же таблицу или в новую таблицу? – Bort

ответ

5
DECLARE @d TABLE (Supplier VARCHAR(32), Quantity INT); 

INSERT @d SELECT 'ABC',3 
UNION ALL SELECT 'BCD',1 
UNION ALL SELECT 'CDE',2 
UNION ALL SELECT 'DEF',1; 

WITH x AS 
(
    SELECT TOP (10) rn = ROW_NUMBER() --since OP stated max = 10 
    OVER (ORDER BY [object_id]) 
    FROM sys.all_columns 
    ORDER BY [object_id] 
) 
SELECT d.Supplier, d.Quantity 
FROM x 
CROSS JOIN @d AS d 
WHERE x.rn <= d.Quantity 
ORDER BY d.Supplier; 
+0

(... double points! Nice work Aaron) Отличный запрос - нет ли более красивого способа заполнения вами CTE? – whytheq

+0

@whytheq как что? Обратите внимание, что OP * just * заявил, что max равен 10. –

+0

Я задал вопрос! Все, что он возвращает, - это список чисел 1,2,3..Max; Я просто подумал, что может быть более красивый способ получить его. – whytheq

2

Отнюдь не самое приятное из вещей; и предполагает, что QTY никогда не будет превышать 10. Есть лучшие способы сделать это ... но будет включать PL \ SQL или T-SQL не может думать о прямом ответе SQL.

Insert into yourTablename 
(
(Select supplier, Qty From YourTableName where Qty-1 > 0) 
UNION 
(Select supplier, Qty From YourTableName where Qty-2 > 0) 
UNION 
(Select supplier, Qty From YourTableName where Qty-3 > 0) 
UNION 
(Select supplier, Qty From YourTableName where Qty-4 > 0) 
UNION 
(Select supplier, Qty From YourTableName where Qty-5 > 0) 
UNION 
(Select supplier, Qty From YourTableName where Qty-6 > 0) 
UNION 
(Select supplier, Qty From YourTableName where Qty-7 > 0) 
UNION 
(Select supplier, Qty From YourTableName where Qty-8 > 0) 
UNION 
(Select supplier, Qty From YourTableName where Qty-9 > 0) 
UNION 
(Select supplier, Qty From YourTableName where Qty-10 > 0) 
) 

Кроме того, это одноразовая сделка; если это не в первый раз; вам придется очистить данные, а затем повторите попытку. (Опять-таки не мой любимый ответ, но ограничивая JUST SQL ...)

+1

, можете ли вы просто изменить приведенное выше на цикл с условием, связанным с максимальным значением Qty – whytheq

+0

Да, но LOOP включает T-SQL и не является строго SQL-ответом. – xQbert

4

Предполагая, что вы вставляете обратно в ту же таблицу, используя КТР, чтобы выяснить, какие строки для вставки работ чисто. Это будет не работать, если количество больше максимального уровня рекурсии (по моему мнению, по умолчанию 100) и, следовательно, не может быть подходящим решением.

;WITH SupplyToInsert (Supplier, Qty) AS (
    SELECT Supplier, Qty - 1 
    FROM Supply 
    WHERE Qty > 1 

    UNION ALL 

    SELECT S.Supplier, I.Qty - 1 
    FROM Supply S 
     INNER JOIN SupplyToInsert I ON I.Supplier = S.Supplier 
    WHERE I.Qty > 1 
) 
INSERT INTO Supply (Supplier, Qty) 
SELECT I.Supplier, S.Qty 
FROM SupplyToInsert I 
    INNER JOIN Supply S ON S.Supplier = I.Supplier 

Если вы Арент вставить обратно в ту же таблицу, сменяют друг Qty > 1 к Qty > 0 в КТР, чтобы получить одну дополнительную строку для каждого поставщика.

Работа SqlFiddle

+0

+1 Creative. Для моего собственного образования: есть: с cte - чисто SQL-решение или ему нужны функции T-SQL? Наверное, я спрашиваю: cte строго ответ SQL. – xQbert

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