Как вставить набор в таблицу?

#sql #sql-server

#sql #sql-сервер

Вопрос:

Предположим, что мне нужно insert ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’ в качестве значений t1.c1 . Это возможно:

 insert into t1(c1, c2, c3)
values
('a', 'c2val', 'c3val'),
('b', 'c2val', 'c3val'),
('c', 'c2val', 'c3val'),
('d', 'c2val', 'c3val'),
('e', 'c2val', 'c3val'),
('f', 'c2val', 'c3val'),
('g', 'c2val', 'c3val'),
('h', 'c2val', 'c3val');
  

Однако, если я намереваюсь insert использовать их с table помощью insert select , то это вызовет синтаксическую ошибку:

 insert into t1(c1, c2, c3)
select ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h') as c1, t2.c2, t2.c3
from t2
where t2.c2 > t2.c3;
  

Вместо этого я должен (?) делать это индивидуально:

 insert into t1(c1, c2, c3)
select 'a' as c1, t2.c2, t2.c3
from t2
where t2.c2 > t2.c3;

insert into t1(c1, c2, c3)
select 'b' as c1, t2.c2, t2.c3
from t2
where t2.c2 > t2.c3;

insert into t1(c1, c2, c3)
select 'c' as c1, t2.c2, t2.c3
from t2
where t2.c2 > t2.c3;

insert into t1(c1, c2, c3)
select 'd' as c1, t2.c2, t2.c3
from t2
where t2.c2 > t2.c3;

insert into t1(c1, c2, c3)
select 'e' as c1, t2.c2, t2.c3
from t2
where t2.c2 > t2.c3;

insert into t1(c1, c2, c3)
select 'f' as c1, t2.c2, t2.c3
from t2
where t2.c2 > t2.c3;

insert into t1(c1, c2, c3)
select 'g' as c1, t2.c2, t2.c3
from t2
where t2.c2 > t2.c3;

insert into t1(c1, c2, c3)
select 'h' as c1, t2.c2, t2.c3
from t2
where t2.c2 > t2.c3;
  

Сегодня мне пришлось написать МНОГО подобных вещей, и я задаюсь вопросом, мог ли я сделать лучше, используя значения как набор, вместо того, чтобы писать insert select для каждого отдельного значения.

Редактировать:

‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’ — это не мои фактические данные, которые на самом деле довольно уродливы и случайны. Буквы использовались исключительно в качестве примера, и мы не должны полагаться на их конкретные атрибуты.

Ответ №1:

не совсем уверен, в чем проблема, сработает ли это?

 insert into t1(c1, c2, c3)
select c1, c2, c3
from 
  (select
    c2, c3
  from
    t2
  where c2 > c3) cross join
(select 'a' as c1 union
select 'b' union
select 'c' union
select 'd' union
select 'e' union
select 'f' union
select 'g' union
select 'h' ) a
  

вы спрашиваете, как создать набор, учитывая кучу уродливых и случайных значений? Если это так, вы можете либо поместить их в таблицу, либо просто union собрать вместе.

Комментарии:

1. Как раз то, что мне было нужно!

Ответ №2:

В этом ответе используется ПЕРЕКРЕСТНОЕ СОЕДИНЕНИЕ, которое создает декартово произведение между пользовательскими данными (буквенными значениями в этом примере) и отфильтрованными данными из таблицы t2 .

 DECLARE @inMemTable as TABLE (someValue varchar(10))
INSERT INTO @inMemTable(someValue) values ('A'), ('B'), ('C'), ('D')

INSERT INTO t1(c1, c2, c3)
SELECT letters.someValue as c1, t2.c2, t2.c3
FROM t2 CROSS JOIN @inMemTable as letters
WHERE t2.c2 > t2.c3
  

Комментарии:

1. Письма были просто примерами. Входными данными в моем случае были случайные данные.

2. @LajosArpad — тогда вам следует обновить свой вопрос, чтобы прояснить это. В любом случае вам нужно перекрестное соединение между списком значений и отфильтрованным содержимым, если вы хотите вставить все возможные комбинации.

3. @LajosArpad — Я обновил свой ответ. Используя параметр таблицы, вы можете определить фрагменты данных, а затем перекрестно соединить их с другой таблицей, чтобы по-прежнему создавать записи для каждой возможной комбинации.

4. Это похоже на решение. Я приму другой ответ, но поддержу и этот, поскольку это конструктивно и полезно.

Ответ №3:

Оберните ваше предложение values в виде производной таблицы.

 Select * from (
values
('a', 'c2val', 'c3val'),
('b', 'c2val', 'c3val'),
('c', 'c2val', 'c3val'),
('d', 'c2val', 'c3val'),
('e', 'c2val', 'c3val'),
('f', 'c2val', 'c3val'),
('g', 'c2val', 'c3val'),
('h', 'c2val', 'c3val')
) t(c1,c2,c3)
  

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