patternsqlMinor
Retrieve Father and Child structure in a Database Table
Viewed 0 times
fatherdatabaseretrievestructurechildandtable
Problem
I have a table with this schema:
(Note: I have excluded all the columns not relevant to the discussion)
I receive an
Every record has the id of the Father stored in the
This is the current full working query:
The perfomance are fine, but I want improve the readability. Any suggestions?
CREATE TABLE [td].[MyTable] (
[ID] [int] NOT NULL
,[FatherID] [int] NULL
)(Note: I have excluded all the columns not relevant to the discussion)
I receive an
[ID] as input, and I need to collect the relative record and all of its fathers in one single output.Every record has the id of the Father stored in the
[FatherID] column. There is only one root element and it is recognized when we found the [FatherID] = 0.This is the current full working query:
IF OBJECT_ID('tempdb..#MyTempTable') IS NOT NULL DROP TABLE #MyTempTable
DECLARE @ID CHAR(11)
SET @ID = 13192
SELECT *
INTO #MyTempTable
FROM [MyTable]
WHERE [ID] = @ID
SELECT @ID = [FatherID]
FROM #MyTempTable
WHERE [ID] = @ID
WHILE @ID <> 0
BEGIN
INSERT INTO #MyTempTable
SELECT *
FROM [MyTable]
WHERE [ID] = @ID
SELECT @ID = [FatherID]
FROM #MyTempTable
WHERE [ID] = @ID
END
SELECT *
FROM #MyTempTable
ORDER BY [ID]The perfomance are fine, but I want improve the readability. Any suggestions?
Solution
Firstly, you use both the
and the
syntax in the same query, using one would make the query much more consistent and easier to read. Personally, I prefer using
If you'd prefer, you can change
to
And you should really explicitly drop the
Lastly, the biggest change I would suggest is to completely remove the selects from outside of the while, they are completely redundant. If you remove those selects from outside the while loop, then the first iteration of the while does exactly the same as the selects on the outside would have done.
Here is what we end up with:
Here is an SQL Fiddle.
SELECT [XYZ]
INTO [ABC]and the
INSERT INTO [ABC]
SELECT [XYZ]syntax in the same query, using one would make the query much more consistent and easier to read. Personally, I prefer using
INSERT INTO [ABC] SELECT [XYZ], you do have to explicitly create the temporary table though, but that makes it usually clearer what is happening.If you'd prefer, you can change
DECLARE @ID CHAR(11)
SET @ID = 13192to
DECLARE @ID CHAR(11) = 13192And you should really explicitly drop the
#MyTempTable at the end of the query.Lastly, the biggest change I would suggest is to completely remove the selects from outside of the while, they are completely redundant. If you remove those selects from outside the while loop, then the first iteration of the while does exactly the same as the selects on the outside would have done.
Here is what we end up with:
IF OBJECT_ID('tempdb..#MyTempTable') IS NOT NULL DROP TABLE #MyTempTable
DECLARE @ID CHAR(11) = 13192
CREATE TABLE #MyTempTable(ID INT, FatherID INT)
WHILE @ID <> 0
BEGIN
INSERT INTO #MyTempTable
SELECT *
FROM [MyTable]
WHERE [ID] = @ID
SELECT @ID = [FatherID]
FROM #MyTempTable
WHERE [ID] = @ID
END
SELECT *
FROM #MyTempTable
ORDER BY [ID]
DROP TABLE #MyTempTableHere is an SQL Fiddle.
Code Snippets
SELECT [XYZ]
INTO [ABC]INSERT INTO [ABC]
SELECT [XYZ]DECLARE @ID CHAR(11)
SET @ID = 13192DECLARE @ID CHAR(11) = 13192IF OBJECT_ID('tempdb..#MyTempTable') IS NOT NULL DROP TABLE #MyTempTable
DECLARE @ID CHAR(11) = 13192
CREATE TABLE #MyTempTable(ID INT, FatherID INT)
WHILE @ID <> 0
BEGIN
INSERT INTO #MyTempTable
SELECT *
FROM [MyTable]
WHERE [ID] = @ID
SELECT @ID = [FatherID]
FROM #MyTempTable
WHERE [ID] = @ID
END
SELECT *
FROM #MyTempTable
ORDER BY [ID]
DROP TABLE #MyTempTableContext
StackExchange Code Review Q#60580, answer score: 4
Revisions (0)
No revisions yet.