Quantcast
Channel: Forum Getting started with SQL Server
Viewing all articles
Browse latest Browse all 7129

[CTE] [Graph] Recursive CTE reports some records 3 times.

$
0
0

Hello & happy new year :)

For my new year resolution, I'll try to better understand & use CTE.

I'm making a graph of animals using this T-SQL code :

CREATE TABLE Species ([Id] int IDENTITY(1,1) NOT NULL,
					[TranslatedNameId] int NULL,
					[ImageIndex] int NULL,
					[Name] nvarchar(64),
					[Description] nvarchar(max) NULL,
					PRIMARY KEY (Id)
					) AS NODE;

CREATE TABLE ChildSpeciesLink AS EDGE;
CREATE TABLE AncestorSpeciesLink AS EDGE;

And fill datas :

Insert Species (TranslatedNameId, ImageIndex, Name, Description) VALUES 
(0, 0, N'Racine', N'Racine de l''arbre.'),
(0, 0, N'animal domestique', N'Animaux domestiques et NAC.'),
(0, 0, N'parc animalier', N'Animaux de parcs zoologiques.'),

(0, 0, N'Chat', N'Chat'),
(0, 0, N'Chien', N'Chien'),
(0, 0, N'Furet', N'Furet'),
(0, 0, N'Rat', N'Rat'),
(0, 0, N'Cochon d''inde', N'Cochon d''inde'),
(0, 0, N'Hamster', N'Hamster'),
(0, 0, N'Chinchilla', N'Chinchilla'),
(0, 0, N'Gerbille', N'Gerbille'),
(0, 0, N'Souris', N'Souris'),
(0, 0, N'Lapin', N'Lapin'),
(0, 0, N'Cheval', N'Cheval'),
(0, 0, N'Âne', N'Âne'),
(0, 0, N'Chêvre', N'Chêvre'),
(0, 0, N'Mouton', N'Mouton'),
(0, 0, N'Cochon', N'Cochon'),
(0, 0, N'Lézard', N'Lézard'),
(0, 0, N'Serpent', N'Serpent'),
(0, 0, N'Tortue', N'Tortue'),
(0, 0, N'Axolotl', N'Axolotl'),
(0, 0, N'Grenouille', N'Grenouille'),
(0, 0, N'Triton', N'Triton');

-- Insertion des espèces canines
Insert Species (TranslatedNameId, ImageIndex, Name, Description) VALUES 
(0, 0, N'Affenpinscher', N'chien - Affenpinscher'),
(0, 0, N'Airedale Terrier', N'chien - Airedale Terrier'),
(0, 0, N'Akita Inu', N'chien - Akita Inu');

Adding the graph :

Insert into ChildSpeciesLink ($to_id,$from_id) values
-- Race Animal domestique:
(
	(select $node_id from dbo.Species where Id=1),
	(select $node_id from dbo.Species where Id=2)
),
-- Race Parc animalier:
(
	(select $node_id from dbo.Species where Id=1),
	(select $node_id from dbo.Species where Id=3)
),
-- Race Chat:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=4)
),
-- Race Chien:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=5)
),
-- Race Furet:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=6)
),
-- Race Rat:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=7)
),
-- Race Cochon d''inde:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=8)
),
-- Race Hamster:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=9)
),
-- Race Chinchilla:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=10)
),
-- Race Gerbille:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=11)
),
-- Race Souris:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=12)
),
-- Race Lapin:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=13)
),
-- Race Cheval:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=14)
),
-- Race Âne:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=15)
),
-- Race Chêvre:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=16)
),
-- Race Mouton:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=17)
),
-- Race Cochon:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=18)
),
-- Race Lézard:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=19)
),
-- Race Serpent:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=20)
),
-- Race Tortue:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=21)
),
-- Race Axolotl:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=22)
),
-- Race Grenouille:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=23)
),
-- Race Triton:
(
	(select $node_id from dbo.Species where Id=2),
	(select $node_id from dbo.Species where Id=24)
),
-- Race Affenpinscher:
(
	(select $node_id from dbo.Species where Id=5),
	(select $node_id from dbo.Species where Id=25)
),
-- Race Airedale Terrier:
(
	(select $node_id from dbo.Species where Id=5),
	(select $node_id from dbo.Species where Id=26)
),
-- Race Akita Inu:
(
	(select $node_id from dbo.Species where Id=5),
	(select $node_id from dbo.Species where Id=27)
);

So, on first level : 1 item ('Racine' / 'root')
on second level : 2 items ('animal domestique' and 'parc animalier')
on third level : 21 items ('chat', 'chien'....) depending from 'animal domestique'
and the last level : 3 items depending from 'chien'
(other items have been removed for comprehension)

The objective is to browse the graph tree to get only once all childs from the root node 'Racine' or a subnode (like 'chien').

Here's my CTE :

DECLARE @@MaxLevel Int; 
DECLARE @@MaxResults Int; 

SET @@MaxLevel = 4;
SET @@MaxResults = 500;

with CTE AS
(
   -- Start node
   SELECT Child.Name AS MyCteChildName,
			Child.Description AS MyCteChildDescription,
			Species1.Name AS MyCteParentName,
			Species1.$node_id AS parentid, 
			Child.$node_id as bottomnode,
			1 AS CurrentLevel
   FROM Species Species1
   JOIN ChildSpeciesLink e ON e.$from_id = Species1.$node_id 
   JOIN Species Child ON Child.$node_id = e.$to_id 
	--AND Species1.Name IN ('Racine')
   UNION ALL
   -- Recurse part
   SELECT r.Name,
			r.Description,
			c.MyCteParentName,
			c.bottomnode,
			r.$node_id, 
			CurrentLevel + 1
   FROM CTE c
   JOIN ChildSpeciesLink e ON e.$from_id = c.bottomnode
   JOIN Species r ON r.$node_id = e.$to_id
   WHERE (CurrentLevel < @@MaxLevel)
)

SELECT TOP (@@MaxResults) MyCteChildName, 
							MyCteChildDescription,
							MyCteParentName,
							CurrentLevel AS MyCteCurrentLevel, 
							@@MaxLevel AS MyCteMaxLevel
FROM CTE

1) Parent name & child name seems to be reversed

2) Current tree level don't seems to work

3) Some records appears more than once

What's wrong with my code ?

Thanks

Vincent


Viewing all articles
Browse latest Browse all 7129

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>