Skip to content

Commit 3fc6ff9

Browse files
Add files via upload
1 parent 9aa5374 commit 3fc6ff9

File tree

3 files changed

+375
-0
lines changed

3 files changed

+375
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*********************************************************************
2+
Scott Peters
3+
https://advancedsqlpuzzles.com
4+
Last Updated: 10/06/2022
5+
6+
This script is written in Microsoft SQL Server's T-SQL
7+
8+
See full instructions in PDF format at the following GitHub repository:
9+
https://github.com/smpetersgithub/AdvancedSQLPuzzles/tree/main/Database%20Tips%20and%20Tricks/Table%20Validation
10+
11+
**********************************************************************/
12+
13+
DROP TABLE IF EXISTS dbo.MyTable1;
14+
DROP TABLE IF EXISTS dbo.MyTable2;
15+
GO
16+
17+
CREATE TABLE dbo.MyTable1
18+
(
19+
TableID INTEGER IDENTITY(1,1) PRIMARY KEY,
20+
CustID INTEGER,
21+
Region VARCHAR(500),
22+
City VARCHAR(500),
23+
Sales MONEY,
24+
ManagerID INTEGER,
25+
AwardStatus VARCHAR(100)
26+
);
27+
GO
28+
29+
CREATE TABLE dbo.MyTable2
30+
(
31+
TableID INTEGER IDENTITY(1,1) PRIMARY KEY,
32+
CustID INTEGER,
33+
Region VARCHAR(500),
34+
City VARCHAR(500),
35+
Sales MONEY,
36+
ManagerID INTEGER,
37+
AwardStatus VARCHAR(100)
38+
);
39+
GO
40+
41+
INSERT INTO dbo.MyTable1 (CustID, Region, City, Sales, ManagerID, AwardStatus) VALUES
42+
(453,'Central','Chicago','71967.99',1324,'Gold'),
43+
(532,'Central','Des Moines','65232.42',6453,'Gold'),
44+
(643,'West','Spokane','44981.23',7542,'Silver'),
45+
(643,'West','Spokane','44981.23',7542,'Silver'),--Duplicate Data
46+
(732,'West','Helena','15232.19',8123,'Bronze'),
47+
(732,'West','Helena','15232.19',8123,'Bronze');--Duplicate Data
48+
GO
49+
50+
INSERT INTO dbo.MyTable2 (CustID, Region, City, Sales, ManagerID, AwardStatus) VALUES
51+
(453,'Central','Chicago','71967.99',1324,'Gold'),
52+
(532,'Central','Des Moines','65232.00',6453,'Gold'),
53+
(643,'West','Spokane','44981.23',7542,'Bronze'),
54+
(643,'West','Spokane','44981.23',7542,'Bronze'),--Duplicate Data
55+
(898,'East','Toledo','53432.78',9242,'Silver');
56+
GO
57+
58+
SELECT 'Table1' AS ID, * FROM dbo.MyTable1
59+
UNION ALL
60+
SELECT 'Table2' AS ID, * FROM dbo.MyTable2;
61+
62+
63+
SELECT * FROM dbo.MyTable1
64+
UNION ALL
65+
SELECT * FROM dbo.MyTable2;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*********************************************************************
2+
Scott Peters
3+
https://advancedsqlpuzzles.com
4+
Last Updated: 10/06/2022
5+
6+
This script is written in Microsoft SQL Server's T-SQL
7+
8+
See full instructions in PDF format at the following GitHub repository:
9+
https://github.com/smpetersgithub/AdvancedSQLPuzzles/tree/main/Database%20Tips%20and%20Tricks/Table%20Validation
10+
11+
**********************************************************************/
12+
13+
DROP TABLE IF EXISTS ##TableInformation;
14+
GO
15+
16+
CREATE TABLE ##TableInformation
17+
(LookupID SMALLINT PRIMARY KEY,
18+
Schema1Name VARCHAR(250) NOT NULL,
19+
Schema2Name VARCHAR(250) NOT NULL,
20+
Table1Name VARCHAR(250) NOT NULL,
21+
Table2Name VARCHAR(250) NOT NULL,
22+
Exists1 VARCHAR(1000) NOT NULL, -- Join condition between Table 1 and Table 2
23+
Exists2 VARCHAR(1000) NOT NULL); -- Join condition between Table 1 and Table 2
24+
GO
25+
26+
27+
INSERT INTO ##TableInformation VALUES (
28+
1---------------LookupID
29+
,'dbo'----------Schema1Name
30+
,'dbo'----------Schema2Name
31+
,'MyTable1'-----Table1Name
32+
,'MyTable2'-----Table2Name
33+
,'CONCAT(t1.CustID, t1.Region, t1.City)'--Exists1 (this must have the prefix "t1.")
34+
,'CONCAT(t2.CustID, t2.Region, t2.City)'--Exists2 (this must have the prefix "t2.")
35+
);
36+
GO
37+
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
/*********************************************************************
2+
Scott Peters
3+
Full Outer Join Create Dynamic SQL
4+
https://advancedsqlpuzzles.com
5+
Last Updated: 10/06/2022
6+
7+
This script is written in Microsoft SQL Server's T-SQL
8+
9+
See full instructions in PDF format at the following GitHub repository:
10+
https://github.com/smpetersgithub/AdvancedSQLPuzzles/tree/main/Database%20Tips%20and%20Tricks/Table%20Validation
11+
12+
**********************************************************************/
13+
SET NOCOUNT ON
14+
15+
----------------------------------------
16+
----------------------------------------
17+
--Tables are created in this order, which I have defined as levels
18+
--The levels are used in the creation of the dynamic SQL for sorting
19+
DROP TABLE IF EXISTS #Select;-------------Level 100
20+
DROP TABLE IF EXISTS #Exists;-------------Level 200
21+
DROP TABLE IF EXISTS #RowNumber;----------Level 300
22+
DROP TABLE IF EXISTS #Count;--------------Level 400
23+
DROP TABLE IF EXISTS #Distinct_Count;-----Level 500
24+
DROP TABLE IF EXISTS #Compare;------------Level 600
25+
DROP TABLE IF EXISTS #Columns;------------Level 600 (Set the QueryOrder to the same value as #Compare to project the _Compare field next to the _Table1 and _Table2 fields)
26+
DROP TABLE IF EXISTS #Into;---------------Level 700
27+
DROP TABLE IF EXISTS #From;---------------Level 800
28+
DROP TABLE IF EXISTS #FullOuterJoin;------Level 900
29+
DROP TABLE IF EXISTS #SQLStatementTemp;-------Used to create dynamic SQL statment
30+
DROP TABLE IF EXISTS #SQLStatementFinal;--Used to create dynamic SQL statment
31+
GO
32+
33+
----------------------------------------
34+
----------------------------------------
35+
--Set this value!!
36+
--It is used to query the ##TableInformation table
37+
DECLARE @LookupID AS INTEGER = 1;-----------------Set this value!!!!!!
38+
39+
-------------------------------------------
40+
-------------------------------------------
41+
--Set variables from the ##TableInformation table
42+
DECLARE @MySQLStatement AS VARCHAR(MAX);
43+
DECLARE @TempTable AS VARCHAR(MAX) = (SELECT CONCAT('##',Table1Name,'_TemporaryTable') FROM ##TableInformation WHERE LookupID = @LookupID);
44+
DECLARE @DropTable AS VARCHAR(MAX) = CONCAT('DROP TABLE IF EXISTS ',@TempTable);
45+
DECLARE @Table1 AS VARCHAR(MAX) = (SELECT Table1Name FROM ##TableInformation WHERE LookupID = @LookupID);
46+
DECLARE @Table2 AS VARCHAR(MAX) = (SELECT Table2Name FROM ##TableInformation WHERE LookupID = @LookupID);
47+
DECLARE @Schema1 AS VARCHAR(MAX) = (SELECT Schema1Name FROM ##TableInformation WHERE LookupID = @LookupID);
48+
DECLARE @Schema2 AS VARCHAR(MAX) = (SELECT Schema2Name FROM ##TableInformation WHERE LookupID = @LookupID);
49+
DECLARE @Exists1 AS VARCHAR(MAX) = (SELECT Exists1 FROM ##TableInformation WHERE LookupID = @LookupID);
50+
DECLARE @Exists2 AS VARCHAR(MAX) = (SELECT Exists2 FROM ##TableInformation WHERE LookupID = @LookupID);
51+
DECLARE @JoinSyntax AS VARCHAR(MAX) = (SELECT CONCAT(Exists1, ' = ', Exists2) FROM ##TableInformation WHERE LookupID = @LookupID);
52+
DECLARE @RowNumberSyntax AS VARCHAR(MAX) = (SELECT Exists1 FROM ##TableInformation WHERE LookupID = @LookupID);
53+
54+
--Drop the temporary table
55+
EXECUTE(@DropTable);
56+
57+
-----------------------------
58+
-----------------------------
59+
--Level_100
60+
--SELECT statement
61+
SELECT 100 AS QueryOrder
62+
,'SELECT ''Start Compare-->'' AS CompareStart' AS SQLStatement
63+
INTO #Select
64+
UNION ALL
65+
SELECT 101, CONCAT(',''',@Schema1, ',', @Table1, ''' AS TableName1')
66+
UNION ALL
67+
SELECT 102, CONCAT(',''',@Schema1, ',', @Table2, ''' AS TableName2')
68+
UNION ALL
69+
SELECT 103, CONCAT(',''',@@SERVERNAME, ''' AS ServerName')
70+
UNION ALL
71+
SELECT 104, CONCAT(',''',@Exists1, ''' AS JoinSyntax_Table1')
72+
UNION ALL
73+
SELECT 105, CONCAT(',''',@Exists2, ''' AS JoinSyntax_Table2');
74+
75+
-----------------------------
76+
-----------------------------
77+
--Level 200
78+
--Exists
79+
SELECT 200 AS QueryOrder
80+
,CONCAT(',CASE WHEN ', @Exists1, ' = '''' THEN 1 ELSE 0 END AS NotExists_Table1') AS SQLStatement
81+
INTO #Exists
82+
UNION ALL
83+
SELECT 210 AS QueryOrder
84+
,CONCAT(',CASE WHEN ', @Exists2, ' = '''' THEN 1 ELSE 0 END AS NotExists_Table2') AS SQLStatement
85+
86+
-----------------------------
87+
-----------------------------
88+
--Level_300
89+
--RowNumber_Table1 (Find Duplicates)
90+
SELECT 300 AS QueryOrder
91+
,CONCAT(',ROW_NUMBER() OVER (PARTITION BY ', @RowNumberSyntax, ' ORDER BY ',@RowNumberSyntax,') AS RowNumber_Table1') AS SQLStatement
92+
INTO #RowNumber
93+
94+
-----------------------------
95+
-----------------------------
96+
--Level 400
97+
--Count_Table1, Count_Table2
98+
SELECT 400 AS QueryOrder
99+
,CONCAT(',', '(SELECT COUNT(*) FROM ',CONCAT(@Schema1,'.',@Table1),') AS Count_Table1') AS SQLStatement
100+
INTO #Count
101+
UNION ALL
102+
SELECT 410 AS QueryOrder
103+
,CONCAT(',', '(SELECT COUNT(*) FROM ',CONCAT(@Schema2,'.',@Table2),') AS Count_Table2') AS SQLStatement
104+
105+
-----------------------------
106+
-----------------------------
107+
--Level 500
108+
--DistinctCount fields
109+
SELECT 500 AS QueryOrder
110+
,CONCAT(',', '(SELECT COUNT(DISTINCT ', @Exists1, ') FROM ',CONCAT(@Schema1,'.',@Table1),' AS t1) AS DistinctCount_Table1') AS SQLStatement
111+
INTO #DISTINCT_COUNT
112+
UNION ALL
113+
SELECT 510 AS QueryOrder
114+
,CONCAT(',', '(SELECT COUNT(DISTINCT ', @Exists2, ') FROM ',CONCAT(@Schema2,'.',@Table2),' AS t2) AS DistinctCount_Table2') AS SQLStatement
115+
UNION ALL
116+
SELECT 520
117+
,CONCAT(',', '(SELECT COUNT(*) FROM ',CONCAT(@Schema1,'.',@Table1),' AS t1 INNER JOIN ',CONCAT(@Schema2,'.',@Table2),' AS t2 ON ',@Joinsyntax,') AS DistinctIntersect')
118+
119+
-----------------------------
120+
-----------------------------
121+
--Level 600
122+
--Compare fields
123+
SELECT DISTINCT
124+
600 AS QueryOrder
125+
,c.Name AS ColumnName
126+
,CONCAT('OR ',c.Name, '_Compare = 1') AS ColumnName_Compare
127+
,CONCAT(',CASE WHEN t1.[',c.name, '] IS NULL AND t2.[',c.name, '] IS NULL THEN 0 WHEN t1.[',c.name, '] = ', 't2.[', c.name, '] THEN 0 ELSE 1 END AS [', c.name,'_Compare]')
128+
AS SQLStatement
129+
INTO #Compare
130+
FROM sys.schemas s LEFT OUTER JOIN
131+
sys.tables t ON s.schema_id = t.schema_id INNER JOIN
132+
sys.columns c ON t.object_id = c.object_id INNER JOIN
133+
sys.types ty ON ty.user_type_id = c.user_type_id
134+
WHERE (t.name = @Table1 AND s.name = @Schema1) OR
135+
(t.name = @Table2 AND s.name = @Schema2);
136+
137+
-----------------------------
138+
-----------------------------
139+
--Level 600
140+
--Creates the Column fields
141+
SELECT 600 AS QueryOrder --Set this value to the same as #Compare to project the _Compare field next to the _Table1 and _Table2 fields
142+
,c.Name AS ColumnName
143+
,CASE WHEN t.name = @Table1 THEN CONCAT(',t1.[',c.name,'] AS [',c.name, '_Table1]')
144+
WHEN t.name = @Table2 THEN CONCAT(',t2.[',c.name,'] AS [',c.name, '_Table2]') END AS SQLStatement
145+
INTO #Columns
146+
FROM sys.schemas s LEFT OUTER JOIN
147+
sys.tables t ON s.schema_id = t.schema_id INNER JOIN
148+
sys.columns c ON t.object_id = c.object_id INNER JOIN
149+
sys.types ty ON ty.user_type_id = c.user_type_id
150+
WHERE (t.name = @Table1 AND s.name = @Schema1)
151+
OR
152+
(t.name = @Table2 AND s.name = @Schema2);
153+
154+
-----------------------------
155+
-----------------------------
156+
--Level 700
157+
--INTO Statement
158+
SELECT 700 AS QueryOrder
159+
,CONCAT('INTO ',@TempTable) AS SQLStatement
160+
INTO #Into;
161+
162+
-----------------------------
163+
-----------------------------
164+
--Level 800
165+
--FROM Statement
166+
SELECT 800 AS QueryOrder
167+
,'FROM' AS SQLStatement
168+
INTO #From;
169+
170+
-----------------------------
171+
-----------------------------
172+
--Level 900
173+
--FULL OUTER JOIN
174+
SELECT 900 AS QueryOrder
175+
,CONCAT(@Schema1,'.',@Table1, ' t1 FULL OUTER JOIN ') AS SQLStatement
176+
INTO #FullOuterJoin
177+
UNION
178+
SELECT 950 AS QueryOrder
179+
,CONCAT(@Schema2,'.',@Table2, ' t2 ON ',@JoinSyntax);
180+
181+
-----------------------------
182+
-----------------------------
183+
--Create table #SQLStatement
184+
--This is then used to create the #SQLStatementFinal table
185+
;WITH CTE_SQLStatement_A AS
186+
(
187+
SELECT QueryOrder
188+
,SQLStatement
189+
FROM #Select
190+
UNION ALL
191+
SELECT QueryOrder
192+
,SQLStatement
193+
FROM #Exists
194+
UNION ALL
195+
SELECT QueryOrder
196+
,SQLStatement
197+
FROM #Distinct_Count
198+
UNION ALL
199+
SELECT QueryOrder
200+
,SQLStatement
201+
FROM #Count
202+
UNION ALL
203+
SELECT QueryOrder
204+
,SQLStatement
205+
FROM #From
206+
UNION ALL
207+
SELECT QueryOrder
208+
,SQLStatement
209+
FROM #FullOuterJoin
210+
),
211+
CTE_SQLStatement_B AS
212+
(
213+
SELECT QueryOrder
214+
,ColumnName AS SortID
215+
,SQLStatement
216+
FROM #Columns
217+
UNION ALL
218+
SELECT QueryOrder
219+
,ColumnName AS SortID
220+
,SQLStatement
221+
FROM #Compare
222+
UNION ALL
223+
SELECT QueryOrder
224+
,CONVERT(VARCHAR(255), NEWID()) SortID
225+
,SQLStatement
226+
FROM CTE_SQLStatement_A
227+
)
228+
SELECT ROW_NUMBER() OVER (ORDER BY QueryOrder, SortID, SQLStatement) AS QueryOrder
229+
,SQLStatement
230+
INTO #SQLStatementTemp
231+
FROM CTE_SQLStatement_B
232+
ORDER BY QueryOrder, SortID, SQLStatement;
233+
234+
-----------------------------
235+
-----------------------------
236+
--Create table #SQLStatementFinal
237+
SELECT 'WITH CTE_SQLStatement AS ( ' AS SQLStatement
238+
INTO #SQLStatementFinal
239+
UNION ALL
240+
SELECT SQLStatement FROM #SQLStatementTemp
241+
UNION ALL
242+
SELECT ') SELECT '
243+
UNION ALL
244+
SELECT 'CASE WHEN '
245+
UNION ALL
246+
SELECT SUBSTRING(STRING_AGG(ColumnName_Compare,' '),4,LEN(STRING_AGG(ColumnName_Compare,' ')))-- REMOVES THE INITIAL 'OR' IN THE CASE STATEMENT
247+
FROM #Compare
248+
UNION ALL
249+
SELECT ' THEN 1 ELSE 0 END AS [Compare_Summary]'
250+
UNION ALL
251+
SELECT ',* '
252+
UNION ALL
253+
SELECT SQLStatement
254+
FROM #Into
255+
UNION ALL
256+
SELECT 'FROM CTE_SQLStatement;'
257+
258+
-----------------------------
259+
-----------------------------
260+
--Places the SQL statement into one line
261+
SELECT @MySQLStatement = STRING_AGG(SQLStatement,' ')
262+
FROM #SQLStatementFinal;
263+
264+
/*
265+
--Display the SQL Statement
266+
SELECT * FROM #SQLStatementFinal;
267+
*/
268+
269+
270+
EXECUTE(@MySQLStatement);
271+
EXECUTE('SELECT DISTINCT * FROM ' + @TempTable + ' ORDER BY 1 DESC, 2,3,4,5'); --The CONCAT function does not work for dynamic sql.
272+
273+
-------------------------------

0 commit comments

Comments
 (0)