2014-01-22 194 views
0

我是初學者用戶,並具有一些SQL的基本知識。我必須編寫一個查詢來從表中選擇記錄並插入到另一個表中。我的TABLE1有近180 +列和TABLE2只有6列。在TABLE2中,前4列是靜態的,將直接來自TABLE1。 TABLE2中的其他2列是動態的。它們將由來自TABLE1的列名稱和列值的180列以上的每列填充。讓我來解釋這一點使用結構,如果它不是很清楚:從另一個查詢插入記錄

>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 = COLUMN_NAME從T1(即COL5,COL6,COL7 ... Col180)
T2.NewCol2 = Column_Value我們正存儲在T2.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

我想在單個動態查詢中實現此目的。格式化的道歉,如果有什麼不明確的。請讓我知道你是否需要任何東西。
謝謝, Sanjay

+2

表中的180列?這是不對的。 –

+0

嗨Deve,其實數據是在我們必須處理和加載在表中的文件中。 –

回答

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) 
; 
+0

感謝帕特里克的回覆。我目前正在這樣做,但正如我所提到的,因爲列數是180+,這使得它成爲一個巨大的查詢。所以我只是想通過一些動態查詢來實現這一點。我的意思是爲每個列創建一個選擇。 –

+0

看看我更新的答案。 –

+0

謝謝帕特里克會試一試,讓你知道。 –

0

的帕特里克與UNION ALL方法的一個小的變化。

100+子查詢聯合沒有什麼問題(儘管最終可能會遇到一些SQL Server限制)。 畢竟,你沒有查詢手工編寫查詢;你可以生成它。 您可以使用元數據查詢來執行此操作;這樣,T1的實際列名將自動出現在生成的查詢中。 在SSMS中運行以下SQL查詢,並選中「結果到文本」;結果是Patrick的原始查詢。

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 
相關問題