#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)
Это даст вам ваш набор значений в виде таблицы, к которой вы можете применить столько условий, сколько захотите.