À l'époque où je travaillais dans un magasin Oracle, je prenais le CONNECT_BY pour acquis. Maintenant, je suis coincé avec SQL Server 2005 et j'ai quelques mauvaises hiérarchies d'objets. Plus précisément, nous avons une table d'auto-référence où tous les enregistrements enfants ont une colonne avec l'ID de leur parent. Actuellement, nous avons une vue qui mappe les enfants aux niveaux de la hiérarchie et une mauvaise requête qui fait le gros du travail pour connecter les parents avec leurs enfants. Bien que cette méthode fonctionne, elle est loin d'être élégante et puante. Je suis juste curieux de savoir comment d'autres personnes récupèrent des données hiérarchiques à partir de SQL Server 2005.Requêtes hiérarchiques dans SQL Server 2005
Répondre
Dans SQL Server 2005, vous pouvez utiliser Common Table Expressions (CTE) pour cela.
Ceci crée votre table hiérarchique typique et utilise un CTE pour sélectionner la structure de la hiérarchie et créer un chemin pour chaque élément.
CREATE TABLE tblHierarchy (ID int, ParentID int NULL, Name varchar(128));
INSERT INTO tblHierarchy VALUES (1, NULL, '1');
INSERT INTO tblHierarchy VALUES (2, NULL, '2');
INSERT INTO tblHierarchy VALUES (3, NULL, '3');
INSERT INTO tblHierarchy VALUES (4, 1, '1.1');
INSERT INTO tblHierarchy VALUES (5, 1, '1.2');
INSERT INTO tblHierarchy VALUES (6, 4, '1.1.1');
WITH Parent AS
(
SELECT
ID,
ParentID,
Name AS Path
FROM
tblHierarchy
WHERE
ParentID IS NULL
UNION ALL
SELECT
TH.ID,
TH.ParentID,
CONVERT(varchar(128), Parent.Path + '/' + TH.Name) AS Path
FROM
tblHierarchy TH
INNER JOIN
Parent
ON
Parent.ID = TH.ParentID
)
SELECT * FROM Parent
SORTIE:
ID ParentID Path
1 NULL 1
2 NULL 2
3 NULL 3
4 1 1/1.1
5 1 1/1.2
6 4 1/1.1/1.1.1
Juste Pour votre information. SQL Server 2008 prend en charge un nouveau type de données Hierarchy ID.
Lire ceci:
http://www.sitepoint.com/article/hierarchical-data-database/2/
Il devrait vous donner quelques idées ...
Oui, les ensembles imbriqués sont définitivement la solution idéale pour les hiérarchies illimitées dans un SGBDR. La description de Sitepoint le rend un peu plus compliqué qu'il ne l'est en réalité, et les implémentations peuvent être simplifiées, par exemple. en ayant un «ordre de classement» et un «rang de voisin» au lieu de «gauche» et «droit». – bobince
Ayant utilisé à la fois, j'ai trouvé CONNECT BY est un peu plus souple et plus facile à utiliser que CTE. La question n'est pas différente de celle à laquelle j'ai répondu il y a quelques semaines. Voir Here pour une brève comparaison de CONNECT BY et CTE et Here pour un exemple d'une requête utilisant CTE.
Tough luck que CONNECT BY n'existe pas dans MSSQL. –
Pour parcourir la profondeur de la hiérarchie d'abord, puis le niveau de frères et soeurs, CTE peut être utilisé:
declare @tempTable TABLE
(
ORGUID int,
ORGNAME nvarchar(100),
PARENTORGUID int,
ORGPATH nvarchar(max)
)
;WITH RECORG(ORGuid, ORGNAME, PARENTORGUID, ORGPATH)
as
(
select
org.UID,
org.Name,
org.ParentOrganizationUID,
dbo.fGetOrganizationBreadcrumbs(org.UID)
from Organization org
where org.UID =1
union all
select
orgRec.UID,
orgRec.Name,
orgRec.ParentOrganizationUID,
dbo.fGetOrganizationBreadcrumbs(orgRec.UID)
from Organization orgRec
inner join RECORG recOrg on orgRec.ParentOrganizationUID = recOrg.ORGuid
)
insert into @tempTable(ORGUID, ORGNAME, PARENTORGUID,ORGPATH)
select ORGUID, ORGNAME, PARENTORGUID,ORGPATH
from RECORG rec
select *
from @tempTable where ORGUID in(select MIN(tt.ORGUID)
from @tempTable tt
group by tt.PARENTORGUID)
la force récursif est un() vous. har har har. –
Pourriez-vous montrer un exemple? –