2015-06-21 2 views
1

У меня есть таблица, которая выглядит следующим образом:Лучший способ вставить все комбинации входных элементов

firstname lastname  address  city 
    a   b   (c,d,e)  (f,g,h) 

Я хочу, чтобы сделать ряд вставок, как это:

insert (a,b,c,f) 
insert (a,b,c,g) 
insert (a,b,c,h) 
insert (a,b,d,f) 
insert (a,b,d,g) 
insert (a,b,e,h) 
.... 

Что является лучшим способ сделать это в SQL Server без использования нескольких курсоров?

+0

Этот стол и те предложения вставки действительно не совпадают - и нигде нет курсора –

+1

Ваш вопрос не очень ясен. что именно вы хотите сделать? –

+0

Я должен разделить адрес и город запятой и вставить все комбинации – user3334778

ответ

2

Вы можете создать временные таблицы и генерировать insert into ... select из декартовых присоединиться:

create table #address(address varchar(1) not null) 

insert into #address 
values ('c'), ('d'), ('e') 

create table #city(city varchar(1) not null) 

insert into #city 
values ('f'), ('g'), ('h') 

insert into my_table 
select 'a', 'b', address, city 
from #address, #city 

http://sqlfiddle.com/#!6/82b9a/2

+0

. Эта инструкция вставки вставляет все комбинации a, b с (c, d, e) и (f, g, h). – user3334778

+0

Вы попробовали? –

+0

Я попробую понедельник на работе, и я дам вам знать спасибо :) – user3334778

6

Просто используйте cross apply с вашим столом и некоторые строки раскалывают udf.
Вы можете найти лучший для вас в this article.

Я использовал для этой демонстрации в SplitStrings_Moden функции из статьи я связан с:

CREATE FUNCTION dbo.SplitStrings_Moden 
(
    @List NVARCHAR(MAX), 
    @Delimiter NVARCHAR(255) 
) 
RETURNS TABLE 
WITH SCHEMABINDING AS 
RETURN 
    WITH E1(N)  AS (SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
         UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
         UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1), 
     E2(N)  AS (SELECT 1 FROM E1 a, E1 b), 
     E4(N)  AS (SELECT 1 FROM E2 a, E2 b), 
     E42(N)  AS (SELECT 1 FROM E4 a, E2 b), 
     cteTally(N) AS (SELECT 0 UNION ALL SELECT TOP (DATALENGTH(ISNULL(@List,1))) 
         ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E42), 
     cteStart(N1) AS (SELECT t.N+1 FROM cteTally t 
         WHERE (SUBSTRING(@List,t.N,1) = @Delimiter OR t.N = 0)) 
    SELECT Item = SUBSTRING(@List, s.N1, ISNULL(NULLIF(CHARINDEX(@Delimiter,@List,s.N1),0)-s.N1,8000)) 
    FROM cteStart s; 

После того как вы функцию расщепления, все вам нужно сделать, это выбрать значения из таблицы и использовать крест применить с помощью этой функции для каждого столбца, разделенных запятыми у вас есть:

-- INSERT INTO MyTable(firstname, lastname, address, city) 
SELECT firstname, lastname, a.item, b.item 
FROM MyTable 
cross apply dbo.SplitStrings_Moden([address], ',') a 
cross apply dbo.SplitStrings_Moden(city, ',') b 

See fiddle here

+0

Очень приятное решение. –

+0

Какая udf более новая/лучше ваша или [это] (http://stackoverflow.com/a/29961649/859154)? –

+0

@RoyiNamir Я думаю, что они почти одинаковы (обратите внимание, что функция split в моем ответе называется 'SplitStrings_Moden', тот же парень, который написал функцию split в ответе wewesthemenace). Прочитайте статью, связанную с ней (или просто посмотрите на графики и перейдите к параграфу «Заключение»), по-видимому, функция CLR от Adam Machanic дает наилучшую производительность практически в каждом случае. –

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