2011-05-31 2 views
3

J'ai un modèle qui ressemble à ceci: Parent a une relation 1-2-M avec Child et Child a une relation 1-2-M avec Sub-Child.SQL: Sélection du dernier sous-enfant

Parent 
------ 
Parent_ID 


Child 
----- 
Child_ID, 
Parent_ID 


Sub-Child 
--------- 
Child_ID, 
Version_Number (numeric), 
Sent (date), 
Void (date) 

Je veux une requête qui renvoie une liste des années PARENT_ID uniques où la dernière version (jugée par le numéro_version) d'un sous-enfant est lié 'sent' == null, mais 'void' != null. J'ai mâché ça dans ma tête et je n'arrive pas à comprendre les choses.

Un conseil serait grandement apprécié.

Merci,

Robert

Répondre

1

Je ne suis pas où je peux tester, mais il semble que vous aurez besoin d'un sous-requête pour tirer les numéros de version max de chaque enfant, puis un autojointure pour obtenir le reste de l'information sous-enfant. Quelque chose comme ce que je pense:

SELECT DISTINCT 
    Parent_ID 
FROM 
    Parent JOIN Child 
    ON Parent.Parent_ID = Child.Parent_ID 
    JOIN (
    SELECT Child_ID, MAX(Version_Number) 
    FROM Sub-Child 
    GROUP BY Child_ID) AS MaxSubchild 
    JOIN Sub-Child 
    ON Sub-Child.Child_ID = MaxSubchild.Child_ID AND 
     Sub-Child.Version_Number = MaxSubchild.Version_Number 
WHERE 
    SUb-Child.Sent IS NULL AND 
    Sub-Child.Void IS NOT NULL; 
3

Ce sera quelque chose comme:

;WITH CTE_LatestSubChildren AS 
(
    SELECT Parent_ID, Latest_Version_Number = max(sc.Version_Number) 
    FROM 
     Child c 
     JOIN [Sub-Child] sc on c.Child_ID = sc.Child_ID 
    GROUP BY c.Parent_ID 

) 
SELECT 
    ParentID 
FROM 
    CTE_LatestSubChildren lsc 
    JOIN Child c 
     on lsc.Parent_ID = c.Parent_ID 
    JOIN [Sub-Child] sc 
     ON sc.Child_ID = c.Child_ID  
     AND sc.version_number = lsc.Latest_Version_Number 
     AND sc.Sent IS NULL  
     AND sc.Void IS NOT NULL 

Notez que cela peut nécessiter des modifications comme non testé, et son pas tout à fait clair ce qui devrait arriver à propos de plusieurs enregistrements enfants où la dernière version est la même.

0

Commencez par obtenir la version par max child_id:

select child_id, max(version_number) as version_number 
from subchild 
group by child_id 

rejoindre ensuite comme une sous-requête, avec subchild et de l'enfant, et appliquez votre condition where.

0

Ou, sans sous-requêtes, essayez,

SELECT DISTINCT p.parent_id 
FROM sub_children sc 
    LEFT JOIN children c ON sc.parent_id = c.child_id 
    LEFT JOIN parents p ON c.parent_id = p.parent_id 
WHERE sc.sent == null, but sc.void != null 
0

Vous pouvez également utiliser Rank():

SELECT DISTINCT TOP 100 PERCENT ST.Parent_ID 
FROM 
(
    SELECT RANK() OVER (PARTITION BY C.Parent_ID ORDER BY SC.Version_Number DESC) AS [RANK], 
    C.Parent_ID, SC.Sent, SC.Void 
    FROM Child C 
    INNER JOIN Sub_Child SC ON C.Child_ID = SC.Child_ID 
) ST 
WHERE [RANK] = 1 
AND [Sent] IS NULL AND [Void] IS NOT NULL 
Questions connexes