Si je tourne cette sous-requête qui sélectionne les personnes de vente et leur prix le plus élevé payé pour tout article qu'ils vendent:SQL: l'amélioration de rejoindre l'efficacité
select *,
(select top 1 highestProductPrice
from orders o
where o.salespersonid = s.id
order by highestProductPrice desc) as highestProductPrice
from salespersons s
pour cette jointure afin d'améliorer l'efficacité:
select *, highestProductPrice
from salespersons s join (
select salespersonid, highestProductPrice, row_number(
partition by salespersonid
order by salespersonid, highestProductPrice) as rank
from orders) o on s.id = o.salespersonid
il touche encore chaque enregistrement de la commande (il énumère toute la table avant de filtrer par SalesPersonID il semble.) Cependant, vous ne pouvez pas le faire:
select *, highestProductPrice
from salespersons s join (
select salespersonid, highestProductPrice, row_number(
partition by salespersonid
order by salespersonid, highestProductPrice) as rank
from orders
where orders.salepersonid = s.id) o on s.id = o.salespersonid
La clause where dans la jointure provoque un `identificateur multi-parties" à l'ID "n'a pas pu être lié.
Existe-t-il un moyen de joindre le top 1 de chaque groupe de commandes avec une jointure sans toucher à chaque enregistrement dans les ordres?
Que voulez-vous dire «touche chaque enregistrement»? Il va falloir toucher tous les records ** pour savoir lequel doit être le top 1 **. Si vous n'avez pas d'index * existant * dans l'ordre souhaité, il doit être exécuté au moment de l'exécution, à chaque fois (il peut mettre en cache les réponses ou créer un index temporaire réutilisable). –
La requête prend beaucoup moins de temps à s'exécuter lorsque vous filtrez l'énumération uniquement sur les enregistrements pouvant être joints. En d'autres termes, ne classer que les enregistrements que je veux classer, et ne pas classer les enregistrements qui ne se joindraient pas en fonction de salespersonid –