![](/img/trans.png)
[英]How do I merge two tables with different column number while removing duplicates for tables with a large number of columns
[英]How do I merge two tables without naming all columns?
所以我說這兩個表有相同的列。 用你的想象力讓它們更大:
USER_COUNTERPARTY:
ID |Name |Credit Rating |Sovereign Risk |Invoicing Type
----+----------------------------+-----------------+------------------+---------------
1 |Nat Bank of Transnistria |7 |93 |Automatic
2 |Acme Ltd. |25 |12 |Automatic
3 |CowBInd LLP. |49 |12 |Manual
TEMP:
ID |Name |Credit Rating |Sovereign Risk |Invoicing Type
----+----------------------------+-----------------+------------------+---------------
2 |Acacacme Ltd. |31 |12 |Manual
4 |Disenthralled Nimrod Corp. |31 |52 |Automatic
我想將它們合並為一個,用第二個替換第一個具有相同ID的內容,並插入不存在的內容。 我可以用這句話:
MERGE INTO USER_COUNTERPARTY C
USING TEMP T
ON (C.COUNTER_ID = T.COUNTER_ID)
WHEN MATCHED THEN UPDATE SET
C.COUNTER_NAME = T.COUNTER_NAME,
C.COUNTER_CREDIT = T.COUNTER_CREDIT,
C.COUNTER_SVRN_RISK = T.COUNTER_SVRN_RISK,
C.COUNTER_INVOICE_TYPE = T.COUNTER_INVOICE_TYPE
WHEN NOT MATCHED THEN INSERT VALUES (
T.COUNTER_ID,
T.COUNTER_NAME,
T.COUNTER_CREDIT,
T.COUNTER_SVRN_RISK,
T.COUNTER_INVOICE_TYPE);
哪個足夠好,但請注意我必須為每個列命名。 有沒有辦法合並這些表而不必命名所有列? Oracle文檔堅持認為我在合並中使用'insert'和'set'之后的列名,因此可能需要一些其他語句。 結果應該是這樣的:
ID |Name |Credit Rating |Sovereign Risk |Invoicing Type
----+----------------------------+-----------------+------------------+---------------
1 |Nat Bank of Transnistria |7 |93 |Automatic
2 |Acacacme Ltd. |31 |12 |Manual
3 |CowBInd LLP. |49 |12 |Manual
4 |Disenthralled Nimrod Corp. |31 |52 |Automatic
如果它有助於我在這里粘貼它:
CREATE TABLE USER_COUNTERPARTY
( COUNTER_ID INTEGER NOT NULL PRIMARY KEY,
COUNTER_NAME VARCHAR(38),
COUNTER_CREDIT INTEGER,
COUNTER_SVRN_RISK INTEGER,
COUNTER_INVOICE_TYPE VARCHAR(10) );
INSERT ALL
INTO USER_COUNTERPARTY VALUES (1, ‘Nat Bank of Transnistria’, 7, 93, ‘Automatic’)
INTO USER_COUNTERPARTY VALUES (2, ‘Acme Ltd.’, 25, 12, ‘Manual’)
INTO USER_COUNTERPARTY VALUES (3, ‘CowBInd LLP.’, 49, 12, ‘Manual’)
SELECT * FROM DUAL;
CREATE TABLE TEMP AS SELECT * FROM USER_COUNTERPARTY;
DELETE FROM TEMP;
INSERT ALL
INTO TEMP VALUES (2, ‘Conoco Ltd.’, 25, 12, ‘Automatic’)
INTO TEMP VALUES (4, ‘Disenthralled Nimrod Corp.’, 63, 12, ‘Manual’)
SELECT * FROM DUAL;
我相信你必須避免使用列名的唯一選擇是兩個單獨的語句:
delete from USER_COUNTERPARTY UC
where exists
(select null
from TEMP T
where T.COUNTER_ID = UC.COUNTER_ID);
insert into USER_COUNTERPARTY UC
select *
from TEMP T
where not exists
(select null
from USER_COUNTERPARTY UC
where T.COUNTER_ID = UC.COUNTER_ID);
您可以嘗試使用這樣的包裝聯合語句:
SELECT (*) FROM
(SELECT * FROM Table1 WHERE ID NOT IN (SELECT ID FROM Table2)
UNION ALL
SELECT * FROM Table2)
ORDER BY 1
我遇到了所描述的問題,我解決它的方式是非常低技術,但我想如果它引發了人們的其他想法,我會分享。
我獲取了列名(我從SQL開發人員的表DDL中提取它們,但也使用tab_columns表中的方法)並將它們插入到Excel電子表格中。 然后我刪除了Varchar等語句(使用文本到列Excel函數,然后只刪除了varchar,number等語句最后的列),所以它只留下了字段名稱。 然后我在下一個Excel列中插入一個公式,=“dest。”&A2&“= src。”&A2&“,”並填寫所有110個字段,然后在新的Excel列中,使用= A2&“,”並在一個新列,=“src。”&A2&“,”,再次填寫所有字段。 然后在SQL表中輸入:
merge into <schema>.<destination_table> dest
using <schema>.<source_table> src
on (dest.<link> = src.<link>)
when matched then update set
(<copy all of the first column,
not including the linking fields and removing the comma at the end>)
when not matched then insert
(<copy and paste the second column from Excel, and remove the final comma>)
values
(<copy and paste the third column from Excel and remove the final comma>)
我還有一個用於合並具有不同列名的表的版本,但這涉及在Excel工作表中映射字段的附加步驟。
我發現我需要使用合並語句來完成我所做的事情 - 與存在的更新相比,我發現Merge可以節省大量時間。
我遇到了同樣的問題,我寫了一個程序,獲取所有表列的列表,並構建動態SQL查詢以進行更新,而無需命名所有列。
PROCEDURE update_from_table(
p_source VARCHAR2, -- Table to copy all columns from
p_target VARCHAR2, -- Table to copy into
p_id_name VARCHAR2 -- Primary key name
)
AS
v_sql VARCHAR2(4096) := 'UPDATE ' || p_target || ' t1 SET (';
v_sql_src VARCHAR2(4096) := ') = (SELECT ';
v_sql_end VARCHAR2(4096) := ' FROM '|| p_source ||' t2 WHERE t1.'||p_id_name||' = t2.'||p_id_name||')
WHERE EXISTS (
SELECT 1
FROM '|| p_source ||' t2
WHERE t1.'||p_id_name||' = t2.'||p_id_name||' )';
v_first BOOLEAN := TRUE;
BEGIN
FOR col IN
(select column_name from user_tab_columns
where table_name = p_source
)
LOOP
IF NOT v_first THEN
v_sql:= v_sql || ', '; -- adding comma before every arg except first
v_sql_src := v_sql_src || ', ';
ELSE
v_first := FALSE;
END IF;
v_sql:= v_sql || col.column_name ;
v_sql_src:= v_sql_src || col.column_name ;
END LOOP;
v_sql := v_sql || v_sql_src || v_sql_end;
EXECUTE IMMEDIATE v_sql;
END update_from_table;
然后我分兩步合並:
-- Insert not matching records
INSERT INTO USER_COUNTERPARTY
SELECT *
FROM TEMP WHERE COUNTER_ID NOT IN (
SELECT USER_COUNTERPARTY.COUNTER_ID
FROM USER_COUNTERPARTY
JOIN TEMP ON TEMP.COUNTER_ID = USER_COUNTERPARTY.COUNTER_ID);
-- Update matching records
update_from_table('TEMP', 'USER_COUNTERPARTY', 'COUNTER_ID');
如果您有列的默認值(並且您希望使用這些默認值),則可以省略insert語句中的那些值,否則,您必須指定要插入或更新值的每個列。
對於SELECT
沒有類似*
簡寫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.