Вставить в таблицу, используя несколько столбцов - PullRequest
0 голосов
/ 09 октября 2018

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

enter image description here

Comma1 Столбец является значением personID, а comma2, comma3, comma4etc (эта таблица создается динамически, поэтому она может содержать более 4 столбцов) являются идентификаторами команды.

Теперь у меня есть еще одна таблица с именем personTeam, которая поддерживает отношения между personids и teamids.Например, если человек 13 является членом команды 3 и команды 8, то в таблице personTeam должно быть 2 записи (13,3 и 13,8).

Что мне нужно, используя эту таблицу вприкрепленное изображение, чтобы вставить personids и teams в таблицу PersonTeam.Например, для человека 149 я хочу вставить (149,10), но для человека 221 я хочу (221,7), (221,8), (221,11).

Есть ли способ обойти это?Спасибо

Ответы [ 4 ]

0 голосов
/ 09 октября 2018

Чтобы он работал с любым количеством столбцов, вы можете построить динамический запрос и выполнить его.

DECLARE @dynSql VARCHAR(max)
DECLARE @table_name VARCHAR(max) = 'tbl'

SELECT @dynSql = (
  SELECT 
     'INSERT INTO personTeam SELECT comma1, ' + 
      COLUMN_NAME + 
     ' FROM ' + 
     @table_name + 
     ' WHERE ' + 
     COLUMN_NAME + 
     ' IS NOT NULL; '
  FROM INFORMATION_SCHEMA.COLUMNS
  WHERE TABLE_NAME = @table_name
  AND ORDINAL_POSITION != 1
  FOR XML PATH('')
)

EXECUTE(@dynSql);

SELECT * FROM personTeam

Просто установите для переменной @table_name имя вашей входной таблицы.

Для этого нужно создать такую ​​строку

INSERT INTO personTeam SELECT comma1, comma2 FROM tbl WHERE comma2 IS NOT NULL;

для каждого столбца (кроме первого; то есть comma2, comma3, ...) в вашей входной таблице, а затем выполнить этот оператор.

http://sqlfiddle.com/#!18/53fcd/24

0 голосов
/ 09 октября 2018

Один из способов сделать это - использовать UNION или UNION ALL

Например:

insert into personTeam (personid, teamid)
select comma1 as personid, comma2 as teamid
from commastable
where comma2 is not null
union
select comma1, comma3
from commastable
where comma3 is not null
union
select comma1, comma4
from commastable
where comma4 is not null;

A UNION будет возвращать только уникальные записи, но для этогоэто должно отсортировать результат.Что может сделать его немного медленнее, чем UNION ALL, который просто склеит результаты объединенных запросов.
Я ожидаю, что исходные данные не будут содержать дубликаты, поэтому UNION просто используется, чтобы убедиться, чтовставляет только уникальные пары.

А если вы хотите сделать это повторяемым?
Просто поместите этот запрос в подзапрос и оставьте присоединиться к нему в personTeam.

insert into personTeam (personid, teamid)
select q.personid, q.teamid
from
(
  -- add the query with the unions here
) as q
left join personTeam as t 
  on (t.personid = q.personid and t.teamid = q.teamid)
where t.personid is null;
0 голосов
/ 09 октября 2018

Если бы я делал это как один раз, я бы просто сделал три вставки.
INSERT INTO personTeam (personids, teamids) SELECT comma1, comma2 from table


INSERT INTO personTeam (personids, teamids) SELECT comma1, comma3 from table WHERE comma2 is null


INSERT INTO personTeam (personids, teamids) SELECT comma1, comma4 from table WHERE comma2 is null and comma3 is null

Команда unpivot используется для нормализации данных в таблицах.Работает только с 2005 года +

insert into personteam (personids, teamids) select comma1, teamids from input unpivot ( teamids for teams in (comma2, comma3, comma4) ) as u;

0 голосов
/ 09 октября 2018

Вы ищете UNPIVOT предложение в SELECT утверждении.

ИСПЫТАТЕЛЬНЫЕ ДАННЫЕ

declare @t1 as table (
    comma1 int,
    comma2 int,
    comma3 int,
    comma4 int 
)

insert into @t1 values
     (149,10,null,null)
    ,(221, 7,8,11)
    ,(278,3,10,null);

select * from @t1;

ПРИМЕР РЕШЕНИЯ

select comma1 as personid , value1
into #TmpTeam
from @t1 unpivot ( value1 for Team in ( comma2,comma3,comma4)) as p;

select * from #TmpTeam;

Вы можете использовать другой синтаксис для вставки результатов запроса в вашу таблицу.Это всего лишь пример.

...