-
Notifications
You must be signed in to change notification settings - Fork 690
/
Copy pathCompare_Tables_With_Matching_Columns.sql
129 lines (115 loc) · 2.76 KB
/
Compare_Tables_With_Matching_Columns.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
<documentation>
<summary>Find all matching column names between tables. Useful for exploring databases with implied relationships but no foreign keys.</summary>
<returns>1 data set: temp table #results.</returns>
<issues>No</issues>
<author>Tom Barrett</author>
<created>2022-08-27</created>
<modified>2022-08-27 by Tom Barrett</modified>
<version>1.0</version>
</documentation>
*/
SET NOCOUNT ON;
/* create staging objects */
IF object_id('tempdb..#tablesToQuery') IS NOT NULL
BEGIN
DROP TABLE #tablesToQuery
END
CREATE TABLE #tablesToQuery (
DatabaseName NVARCHAR(1000)
, SchemaName NVARCHAR(1000)
, TableName NVARCHAR(1000)
, IsProcessed BIT DEFAULT 0
)
GO
IF object_id('tempdb..#results') IS NOT NULL
BEGIN
DROP TABLE #results
END
CREATE TABLE #results (
DatabaseName NVARCHAR(1000)
, ColumnName NVARCHAR(1000)
, Table1 NVARCHAR(1000)
, Table2 NVARCHAR(1000)
)
GO
/* get list of tables */
INSERT INTO #tablesToQuery (
DatabaseName
, SchemaName
, TableName
)
SELECT TABLE_CATALOG
, TABLE_SCHEMA
, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
ORDER BY TABLE_CATALOG
, TABLE_SCHEMA
, TABLE_NAME
GO
/* loop through tables and get matching columns by name */
DECLARE @x INT = 1;
DECLARE @table NVARCHAR(1000);
WHILE @x <= (
SELECT count('dracula')
FROM #tablesToQuery
WHERE IsProcessed = 0
)
BEGIN
/* get next table*/
SELECT TOP 1 @table = TableName
FROM #tablesToQuery
WHERE IsProcessed = 0;
/* insert into #results any tables + columns that match */
WITH cte
AS (
SELECT TABLE_CATALOG
, TABLE_SCHEMA
, TABLE_NAME
, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
)
INSERT INTO #results
SELECT cte1.TABLE_CATALOG
, cte1.COLUMN_NAME
, CONCAT (
cte1.TABLE_SCHEMA
, '.'
, cte1.TABLE_NAME
)
, CONCAT (
cte2.TABLE_SCHEMA
, '.'
, cte2.TABLE_NAME
)
FROM cte AS cte1
JOIN cte AS cte2 ON cte1.TABLE_CATALOG = cte2.TABLE_CATALOG
AND cte1.TABLE_SCHEMA collate Latin1_general_CI_AI = cte2.TABLE_SCHEMA collate Latin1_general_CI_AI /* remove this line to search different schemas*/
AND cte1.TABLE_NAME collate Latin1_general_CI_AI <> cte2.TABLE_NAME collate Latin1_general_CI_AI
AND cte1.COLUMN_NAME collate Latin1_general_CI_AI = cte2.COLUMN_NAME collate Latin1_general_CI_AI
WHERE cte1.TABLE_NAME = @table
/* add any other irrelevant or metadata columns to exclude */
AND cte1.COLUMN_NAME collate Latin1_general_CI_AI NOT IN (
'ID'
, 'ACTIVE'
, 'CREATEDBY'
, 'ETC.'
)
UPDATE #tablesToQuery
SET IsProcessed = 1
WHERE TableName = @table;
END
/* return results */
SELECT *
FROM #results
/* uncomment this line to search results for a specific table */
/* WHERE Table1 = 'Schema.Table' */
ORDER BY ColumnName
, Table1
, Table2
GO
/* clean up */
DROP TABLE #results
GO
DROP TABLE #tablesToQuery
GO