2011-06-13 8 views
6

Ci scusiamo per il tema non valido. Non riuscivo a pensarne uno migliore e ho fretta.La funzione di aggregazione che seleziona il valore di una colonna che corrisponde a un'altra funzione aggregata di successo corrisponde a

dire che ho le seguenti tabelle:

Parent

  • Id
  • Nome
  • ...

Bambino

  • Id
  • ParentId
  • Età
  • ...

C'è una relazione uno-a-molti tra genitore e figlio.

Ora voglio costruire una query che restituisce tutti i genitori e il loro figlio minore. Voglio che il risultato sia simile a questo:

Risultato

  • Parent.Id
  • Child.Id
  • Child.Age

Ci dovrebbe essere anche solo una riga per Parent.Id nel risultato.

Ecco un'immagine che spiega quello che voglio

http://i.stack.imgur.com/L6PjL.png

Questo è dove mi trovo ora:

SELECT 
Parent.Id AS ParentId, 
Child.Id AS ChildId, 
MIN(Child.Age) AS ChildAge -- OVER (PARTITION BY Parent.Id) AS ChildAge 
FROM Parent JOIN Child ON Parent.Id = Child.ParentId 
GROUP BY Parent.Id, Child.Id 

quello che vorrei è una funzione di aggregazione per mettere intorno Bambino. Id che recuperava Child.Id che corrisponde alla riga MIN (Child.Age). Non riesco a trovare nulla di simile e non riesco a emulare il comportamento.

Qualsiasi aiuto è molto apprezzato!

+0

Il sistema richiedeva di avere una certa reputazione prima di consentire le immagini in linea, ma sono sicuro che non ci vorrà molto tempo prima di averlo. Ho modificato per portare la tua immagine in linea per te. – AakashM

+0

Sì, me l'ha detto. Ragionevole. Grazie per la modifica! :) –

risposta

6

tua idea di utilizzare OVER con un PARTITION BY ParentId è nella giusta direzione; tuttavia, anziché utilizzarlo con MIN, utilizzarlo con un ROW_NUMBER() per ottenere l'intera riga. Questo:

SELECT 
    ParentId 
    , Id 
    , Age 
    , ROW_NUMBER() OVER (PARTITION BY ParentId ORDER BY Age) AS rn 
FROM Child 

restituisce tutti i bambini, insieme a un numero di riga che indica l'ordine di età entro figli dello stesso padre, quindi abbiamo solo bisogno di filtrare che:

SELECT ParentId, Id, Age FROM (
    SELECT 
     ParentId 
     , Id 
     , Age 
     , ROW_NUMBER() OVER (PARTITION BY ParentId ORDER BY Age) AS rn 
    FROM Child 
) c -- need to alias the subquery in order to SELECT from it 
WHERE rn = 1 


ParentId Id   Age 
----------- ----------- ----------- 
1   11   2 
2   13   4 
3   15   3 
4   19   1 

Nota che mentre chiedi "tutti i genitori e il loro figlio minore", puoi prendere in considerazione ciò che vuoi restituito per i record in Parent con no record corrispondenti in Child - la mia soluzione, insieme a tutti gli altri, non includeranno alcuna informazione su tali record Parent.

+0

+1 per spiegare la risposta. –

1
SELECT 
Parent.Id AS ParentId, 
C.Id AS ChildId, 
C.Age AS ChildAge 
FROM Parent, CHILD C 
WHERE PARENT.ID = C.ParentId 
AND C.AGE = 
(
    SELECT MIN(AGE) 
    FROM CHILD 
    WHERE ParentId = C.ParentId 

) 
-1

Questo potrebbe funzionare:

SELECT 
ParentID, 
ChildId, 
ChildAge 
FROM 
(

SELECT 
Parent.Id AS ParentId, 
Child.Id AS ChildId, 
MIN(Child.Age) AS ChildAge, 
Ranking = ROW_NUMBER() OVER(PARTITION BY ParentID order by Child.Age asc) 

FROM Parent JOIN Child ON Parent.Id = Child.ParentId 
GROUP BY Parent.Id, Child.Id, Child.Age 
)A 
Where Ranking =1 
-2

si può provare qualcosa di simile:

SELECT parentid, id, age FROM child c 
WHERE age = (SELECT MIN(c2.age) FROM child c2 WHERE c2.parentid = c.parentid); 

Nota che si possono trovare più di un bambino per genitore (se hanno lo stesso , età minima).

+0

d'oh, ero troppo tardi :) – Vincent

+1

Ricontrolla la tua richiesta. Non è corretto. "id" non appartiene al bambino. Ci sono anche altri problemi. –

1
SELECT 
    Parent.Id AS ParentId, 
    Child.Id AS ChildId, 
    Child.Age AS ChildAge 
FROM Parent 
    JOIN Child 
    ON Parent.Id = Child.ParentId 
    JOIN 
    (SELECT ParentId, 
      MIN(Age) AS ChildAge 
     FROM Child 
     GROUP BY ParentId 
    ) AS minCh 
    ON Child.ParentId = minCh.ParentId 
    AND Child.Age = minCh.ChildAge 
Problemi correlati