這裏是場景:如何比較兩個表中具有複合主鍵的行?
我有2個數據表,一個是2009年的版本,另一個是2010年的版本。每個表的主鍵都是一個組合鍵。我知道每一行都有不同的行數,我需要找出差異。
通常,在「正常」主鍵設置中,我只需查找其他表中主鍵列表中的主鍵值NOT。但我不知道如何用複合主鍵(或者即使有可能)來做到這一點。
那麼,我怎樣才能比較這兩個表中的行?
編輯:更具體地說,我試圖找到表之間的差異,而不是行共同
這裏是場景:如何比較兩個表中具有複合主鍵的行?
我有2個數據表,一個是2009年的版本,另一個是2010年的版本。每個表的主鍵都是一個組合鍵。我知道每一行都有不同的行數,我需要找出差異。
通常,在「正常」主鍵設置中,我只需查找其他表中主鍵列表中的主鍵值NOT。但我不知道如何用複合主鍵(或者即使有可能)來做到這一點。
那麼,我怎樣才能比較這兩個表中的行?
編輯:更具體地說,我試圖找到表之間的差異,而不是行共同
只是做一個完整的外部與條件聯接基於你的組合鍵:
select t09.*, t10.*
from table2009 as t09
full outer join table2010 as t10
on t09.k1 = t10.k1 and t09.k2 = t10.k2 and ...
如果你只希望看到的結果本身不匹配的行(差) T,那麼where
子句中進行篩選:
where t09.k1 is null or t10.k1 is null
select * from [table2009] right outer join [table2010] on [table2009].[PK1] = [table2010].[PK2] and [table2009].[PK2] = [table2010].[PK2] where [table2009].[PK1] is null
你可以採取複合列的校驗和整個表進行比較,以使連接更加緊湊一些。
select ...
--------------------------
--or left outer join etc.
--------------------------
from a inner join b
on checksum(a.col1, a.col2, a.col3) = checksum(b.col1, b.col2, b.col3)
假設你不想比較所有的列。
DECLARE @Table2009 TABLE
( Year INT
,Counter INT IDENTITY (-2147483647 , 1)
,OtherData CHAR(1)
,PRIMARY KEY (Year, Counter)
);
DECLARE @Table2010 TABLE
( Year INT
,Counter INT IDENTITY (-2147483647 , 1)
,OtherData CHAR(1)
,PRIMARY KEY (Year, Counter)
);
SELECT 'NOT IN Table2010'
,Table2009.Year
,Table2009.Counter
FROM @Table2009 Table2009
LEFT JOIN @Table2010 Table2010 ON Table2009.Year = Table2010.Year
AND Table2009.Counter = Table2010.Counter
WHERE Table2010.Year IS NULL
UNION
SELECT 'NOT IN Table2010'
,Table2009.Year
,Table2009.Counter
FROM @Table2010 Table2010
LEFT JOIN @Table2009 Table2009 ON Table2010.Year = Table2009.Year
AND Table2010.Counter = Table2009.Counter
WHERE Table2009.Year IS NULL;
一些數據來測試:
CREATE TABLE Tbl_1 (
ID1 integer NOT NULL
, ID2 int NOT NULL
, SomeData varchar(20)
);
ALTER TABLE Tbl_1 ADD
CONSTRAINT pk_tbl_1 PRIMARY KEY (ID1, ID2);
CREATE TABLE Tbl_2 (
ID1 integer NOT NULL
, ID2 int NOT NULL
, SomeData varchar(20)
);
ALTER TABLE Tbl_2 ADD
CONSTRAINT pk_tbl_2 PRIMARY KEY (ID1, ID2);
INSERT INTO Tbl_1
(ID1, ID2, SomeData)
VALUES
(1, 1, '1_1')
, (2, 2, '2_2')
, (3, 3, '3_3')
;
INSERT INTO Tbl_2
(ID1, ID2, SomeData)
VALUES
(1, 1, '1_1')
, (3, 3, '3_3')
, (4, 4, '4_4')
;
...
-- All rows that are in the first table,
-- but not in the second one
SELECT
a.ID1 AS t1_ID1
,a.ID2 AS t1_ID2
,a.SomeData AS t1_SomeData
,b.ID1 AS t2_ID1
,b.ID2 AS t2_ID2
,b.SomeData AS t2_SomeData
FROM Tbl_1 as a
LEFT JOIN Tbl_2 as b ON b.ID1 = a.ID1 AND b.ID2 = a.ID2
WHERE b.ID1 IS NULL;
返回:
t1_ID1 t1_ID2 t1_SomeData t2_ID1 t2_ID2 t2_SomeData
------- -------- ------------- -------- -------- -----------
2 2 2_2 NULL NULL NULL
...
-- All rows that are in the second table,
-- but not in the first one
SELECT
a.ID1 AS t1_ID1
,a.ID2 AS t1_ID2
,a.SomeData AS t1_SomeData
,b.ID1 AS t2_ID1
,b.ID2 AS t2_ID2
,b.SomeData AS t2_SomeData
FROM Tbl_1 as a
RIGHT JOIN Tbl_2 as b ON b.ID1 = a.ID1 AND b.ID2 = a.ID2
WHERE a.ID1 IS NULL;
返回:
t1_ID1 t1_ID2 t1_SomeData t2_ID1 t2_ID2 t2_SomeData
------- ------- ------------- -------- ------- ------------
NULL NULL NULL 4 4 4_4
...
-- Common to both tables
SELECT
a.ID1 AS t1_ID1
,a.ID2 AS t1_ID2
,a.SomeData AS t1_SomeData
,b.ID1 AS t2_ID1
,b.ID2 AS t2_ID2
,b.SomeData AS t2_SomeData
FROM Tbl_1 as a
JOIN Tbl_2 as b ON b.ID1 = a.ID1 AND b.ID2 = a.ID2;
返回
t1_ID1 t1_ID2 t1_SomeData t2_ID1 t2_ID2 t2_SomeData
----------- ----------- ------------- ----------- ----------- ------------
1 1 1_1 1 1 1_1
3 3 3_3 3 3 3_3
我用這個樣子!只有一個左外連接。
,我用另一場檢查狀態
SELECT * FROM actas LEFT OUTER JOIN acta_detalle_proceso on actas.id = acta_detalle_proceso.id
and actas.tipo_acta_id = acta_detalle_proceso.tipo_acta_id and acta_detalle_proceso.estado = 1
WHERE acta_detalle_proceso.id IS NULL and acta_detalle_proceso.tipo_acta_id IS NULL ;
-- Entity in Tbl_1 only
SELECT ID1, ID2
FROM Tbl_1
EXCEPT
SELECT ID1, ID2
FROM Tbl_2;
-- Entity in Tbl_2 only
SELECT ID1, ID2
FROM Tbl_2
EXCEPT
SELECT ID1, ID2
FROM Tbl_1;
-- Entity in both tables
-- with same attribute values
SELECT ID1, ID2, SomeData
FROM Tbl_1
INTERSECT
SELECT ID1, ID2, SomeData
FROM Tbl_2;
-- Entity in both tables but
-- with different attribute values
SELECT DISTINCT T1.ID1, T1.ID2,
T1.SomeData AS Tbl_1__SomeData,
T2.SomeData AS Tbl_2__SomeData
FROM Tbl_1 AS T1, Tbl_2 AS T2
WHERE T1.ID1 = T1.ID1
AND T1.ID2 = T2.ID2
AND T1.SomeData <> T2.SomeData;
補充說,「差異化」你在談論;但是,您可能只想找到一側(例如,2010年的那些行沒有出現在2009年的表中) - 那麼左連接就可以實現。 – incarnate 2010-03-12 21:27:06