我是初学者用户,并且具备一些SQL的基本知识。我必须编写一个查询来从表中选择记录并插入到另一个表中。我的TABLE1有近180列,TABLE2只有6列。在TABLE2中,前4列是静态的,将直接来自TABLE1。 TABLE2中的其他2列是动态的。它们将由180多列中的每一列填充,其中列名和列值来自TABLE1。如果不是很清楚,让我用结构解释一下:
>T1:
>===
>Col1, Col2, Col3, Col4, Col5,..........,Col175, Col176, Col177, Col178, Col179, Col180
>
>T2:
>===
>Col1, Col2, Col3, Col4, NewCol1, NewCol2
所以我想要一个查询来从T1中选择记录并将它们插入到T2中,以便
T2.Col1 = T1.Col1
T2.Col2 = T1.Col2
T2.Col3 = T1.Col3
T2.Col4 = T1.Col4
T2.NewCol1 =来自T1的Column_Name(即Col5,Col6,Col7 ...... Col180)
T2.NewCol2 =我们存储在T2中的列的Column_Value.NewCol2
以下是示例:
T1:
Col1 | Col2 | Col3 | Col4 | Col5 | Col6 | Col7 | Col8 | Col9 | Col10 | Col11 | Col12
Val1 | Val2 | Val3 | Val4 | Val5 | Val6 | Val7 | Val8 | Val9 | Val10 | Val11 | Val12
T2:
Col1 | Col2 | Col3 | Col4 | Col5 | Col6
Val1 | Val2 | Val3 | Val4 | Col5 | Val5
Val1 | Val2 | Val3 | Val4 | Col6 | VAL6
Val1 | Val2 | Val3 | Val4 | Col7 | Val7
Val1 | Val2 | Val3 | Val4 | Col8 |的Val8
Val1 | Val2 | Val3 | Val4 | Col9 | Val9
。
。
Val1 | Val2 | Val3 | Val4 | Col12 | Val12
我想在单个动态查询中实现此目的。对格式化表示歉意,如果有什么不清楚的话。如果您需要什么,请告诉我 谢谢, 桑杰
答案 0 :(得分:0)
您可以使用联合来选择所有项目及其值。
select col1
, col2
, col3
, col4
, 'col5' col_name
, col5 col_value
from t1
union
all
select col1
, col2
, col3
, col4
, 'col6' col_name
, col6 col_value
from t1
......等等
另一种选择是流水线功能:
create type x_rec is object
( col1 varchar2(200)
, col2 varchar2(200)
, col3 varchar2(200)
, col4 varchar2(200)
, col5 varchar2(200)
, col6 varchar2(200)
);
;
create type x_tab is table of x_rec;
create or replace function x
return x_tab
pipelined
is
begin
for r
in
( select *
from y
)
loop
pipe row (r.col1, r.col2, r.col3, r.col4, 'col5', r.col5);
pipe row (r.col1, r.col2, r.col3, r.col4, 'col6', r.col6);
-- etc
end loop;
--
return;
end;
select *
from table(x)
;
答案 1 :(得分:0)
Patrick与UNION ALL的方法略有不同。
100个子查询的并集没有任何问题(尽管最终可能会遇到一些SQL Server限制)。
毕竟,你没有查询手写的查询;你可以生成它。
您可以使用元数据查询来执行此操作;这样,T1
的实际列名称将自动出现在生成的查询中。
在SSMS中运行以下SQL查询,并选择“结果到文本”;结果是帕特里克的原始查询。
SELECT CASE WHEN ROW_NUMBER() OVER(ORDER BY COLUMN_NAME) = 1 THEN
'INSERT INTO T2 (Col1, Col2, Col3, Col4, NewCol1, NewCol2)'
ELSE
'UNION ALL'
END +
' SELECT Col1, Col2, Col3, Col4, ''' + COLUMN_NAME + ''', ' + QUOTENAME(COLUMN_NAME) +
' FROM T1'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'T1'
AND COLUMN_NAME NOT IN (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'T2')
ORDER BY COLUMN_NAME
更进一步,您可以使用动态SQL在单个SQL语句中组合这两个步骤(检索元数据和复制数据)。
在下面的示例中,不仅从元数据中检索“动态”列名称(Col5-Col180),还检索“静态”列名称(Col1-Col4)。
出现在两个表中的任何列都被视为“静态”;显示在T1
但不在T2
中的列被视为“动态”。如果需要排除某些列,请向元数据查询添加WHERE条件。
-- build up a string of 'static' column names
DECLARE @columnName sysname
DECLARE @columnNames nvarchar(999) = ''
DECLARE staticColumns CURSOR FOR
SELECT c1.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS c1
INNER JOIN INFORMATION_SCHEMA.COLUMNS c2 ON c2.COLUMN_NAME = c1.COLUMN_NAME
WHERE c1.TABLE_NAME = 'T1' AND c2.TABLE_NAME = 'T2'
OPEN staticColumns
FETCH NEXT FROM staticColumns INTO @columnName
WHILE @@FETCH_STATUS = 0 BEGIN
SET @columnNames = @columnNames + QUOTENAME(@columnName) + ', '
FETCH NEXT FROM staticColumns INTO @columnName
END
CLOSE staticColumns
DEALLOCATE staticColumns
-- for each 'dynamic' column in T1, build and execute an INSERT...SELECT statement
DECLARE @insertSelect nvarchar(999)
DECLARE dynamicColumns CURSOR FOR
SELECT 'INSERT INTO T2 (' + @columnNames + 'NewCol1, NewCol2)' +
' SELECT ' + @columnNames + '''' + COLUMN_NAME + ''', ' + QUOTENAME(COLUMN_NAME) +
' FROM T1'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'T1'
AND COLUMN_NAME NOT IN (SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'T2')
ORDER BY COLUMN_NAME
OPEN dynamicColumns
FETCH NEXT FROM dynamicColumns INTO @insertSelect
WHILE @@FETCH_STATUS = 0 BEGIN
EXEC(@insertSelect)
FETCH NEXT FROM dynamicColumns INTO @insertSelect
END
CLOSE dynamicColumns
DEALLOCATE dynamicColumns