2010-08-15 4 views
4

Je ne suis pas sûr si je devrais le faire dans le code ou le faire dans la requête, mais je vais le demander ici car je suis intéressé par une solution SQL pour moi-même.aide avec la requête SQL?

Say si je le tableau suivant, et je dois obtenir toutes les lignes dont ParentSID est . Mais si l'une de ces lignes ont retour Null comme alors je FID aussi besoin d'aller chercher toutes les lignes dont ParentSID est le SID de la ligne dont était FID nul.

Il n'y a pas de limite et il pourrait aller et où les dossiers de retour pourrait avoir Null comme FIDs et je dois trouver toutes les lignes avec son ParentSID.

---------------------- 
SID FID ParentSID 

1  null null   
2  null null 
3  16  1 
4  17  1 
5  null 1 
6  18  5 
7  19  2 
---------------------- 

je solution itérative dans le code mais je dois revenir plusieurs fois à la base de données pour obtenir la liste complète Je suis intéressé et je suis sûr d'avoir une procédure SQL aurait du sens beaucoup plus, mais je suis Vous ne savez pas comment le faire?

Merci,

Voodoo

+2

SQL Server? MySQL? Quelle version? – LittleBobbyTables

+0

Est-il possible d'avoir une ligne avec FID = NULL et ParentSID! = NULL qui ne renvoie pas à 1? Si c'est le cas, une dénormalisation serait peut-être appropriée et l'ajout du champ RootParentSID au parent ultime de chaque rangée serait utile. – aepryus

+0

MSSQL Server 2008 – VoodooChild

Répondre

2

je devais utiliser deux CTEs récursive, l'un sur l'autre, pour obtenir la sortie, je crois que vous attendez:

WITH hierarchy AS (
    SELECT * 
     FROM dbo.[Table] 
    WHERE parentsid = 1 
    UNION ALL 
    SELECT t.* 
     FROM hierarchy h 
     JOIN dbo.[Table] t ON h.sid = t.parentsid 
         AND t.fid IS NULL), 
    h2 AS (
    SELECT h.* 
     FROM hierarchy h 
    UNION ALL 
    SELECT t.* 
     FROM hierarchy h 
     JOIN dbo.[Table] t ON h.sid = t.parentsid 
         AND t.fid IS NOT NULL)  
SELECT * 
    FROM h2 

Le premier obtient tous ceux qui sont NULL; la seconde obtient les doglegs où le fid n'est pas nul.

+0

Merci d'avoir répondu à ma question et de m'avoir appris quelque chose que je ne connaissais pas (CTE) - des liens recommandés qu'un débutant devrait lire? – VoodooChild

+1

@VoodooChild: Désolé, j'ai oublié de transmettre ce lien: http://www.4guysfromrolla.com/webtech/071906-1.shtml –

+0

Merci, c'est génial! – VoodooChild

1

Ce genre est un problème classique, je suppose. Vous pouvez jeter un oeil ici: Récursion dans T-SQL. À mon humble avis, cependant, il pourrait être utile de considérer si vous pouvez aplatir votre structure de données ailleurs (c'est-à-dire un cache dans une autre table), puis interroger plus facilement. Dépend de vous. La recherche de divers 'T-SQL récursifs' devrait vous conduire à des options intéressantes, si vous décidez de faire la boucle là-bas. FWIW, quand j'ai rencontré ça, je viens de le faire dans le code (mais mon contexte peut être différent du vôtre).

1

La requête suivante vous donne ce qui est attendu. select * from @table A où ParentSID = 1 OU ParentSID IN (sélectionnez SID de @table A où ParentSID = 1 ET NULL est FID)

J'ai illustré cela dans un exemple

Exemple

declare @table table ([SID] int, FID int, ParentSID int) 

insert into @table Values(1, null, null) 
insert into @table Values(2, null, null) 
insert into @table Values(3, 16, 1) 
insert into @table Values(4, 17, 1) 
insert into @table Values(5, null, 1) 
insert into @table Values(6, 18, 5) 
insert into @table Values(7, null, 1) 
insert into @table Values(8, 19, 7) 

select * from 
    @table A 
where ParentSID=1 OR 
ParentSID IN (select SID from 
    @table A 
where ParentSID=1 AND FID is NULL) 
0

Ceci est très simple:

if(not exists(select * 
       from table 
       where FID is null 
         and 
         ParentSID = 1) ) 

    select 
     * 
    from 
     table 
    where 
     ParentSID = 1 
else 
    select 
     * 
    from 
     table 
    where 
     ParentSID = SID