2017-07-05 3 views
3

J'ai une requête où je veux récupérer des lignes child2 distinctes, mais ordonnées par une propriété de child1 lignes qui sont liées par un parent commun. Si je fais ce qui suit, je reçois une erreur car la ORDERBY propriété est pas dans la liste DISTINCT:SQL: Sélectionnez les enfants distincts classés par propriété de l'enfant apparenté

select 
    distinct c2.Id, c2.Foo, c2.Bar 
    from Child1 c1 
    join Parent p on c1.parentId = p.Id 
    join Child2 c2 on c2.parentId = p.Id 
    order by c1.Id 

Cependant, si j'ajoute c1.Id à la liste de sélection, je vais perdre la netteté de Child lignes, comme c1.Id marques tous sont distincts.

Si j'utilise un CTE ou une sous-requête pour effectuer la commande, puis sélectionner des lignes distinctes, la requête externe ne garantit pas le maintien de l'ordre de la requête interne/cte.

Existe-t-il un moyen d'y parvenir?

+0

Pouvez-vous fournir votre structure de table s'il vous plaît? – jimmy8ball

+0

Donc si vous avez deux lignes avec le même 'c.foo' i' c.bar' et différent 'p.createdate', lequel des deux' createate' voulez-vous utiliser? –

+0

@Nenad il y aurait la clé primaire de l'enfant aussi, je vais l'ajouter à l'exemple – GoatInTheMachine

Répondre

0

en utilisant le tableau Inline:

Select DISTINCT t.foo, t.bar From 
    (SELECT 
    c.foo, c.bar, p.createdDate 
    FROM Parent p 
    JOIN Child c on c.parentId = p.id 
)t 
    ORDER BY t.createdDate 
3

Je fais des lignes distinctes dans cte en utilisant TOP(1) WITH TIES, puis trier dans la requête

WITH Data AS(
    SELECT TOP(1) WITH TIES 
     g.id, g.foo, g.bar, p.createdDate 
    FROM Parent p 
    JOIN Child c on c.parentId = p.id 
    JOIN Grandchild g on g.childId = c.id 
    ORDER BY ROW_NUMBER() OVER(PARTITION BY g.id, g.foo, g.bar ORDER BY p.createdDate) 
) 
SELECT * 
FROM Data 
ORDER BY createdDate 

TOP(1) WITH TIES sélectionne les lignes où ROW_NUMBER().. = 1. En raison de PARTITION BY ... il sélectionne une ligne par partition (groupe). Cela fonctionne similaire à GROUP BY mais permet de retourner toutes les colonnes

+0

Est-ce que le second 'outer' ne choisira pas de 'Data' mais passera-t-il lui-même la commande? Je ne pense pas qu'il est garanti de maintenir la commande du CTE? – GoatInTheMachine

+1

Je ne comprends pas votre question. La sélection 'Outer' est nécessaire pour le tri par 'createdDate' uniquement. CTE ne fournit aucun tri (j'utilise 'order by' à' select distinct') –

+0

Mon mauvais, n'a pas vu que ... Je vais l'essayer ... – GoatInTheMachine