Comment puis-je exclure les tables LEFT JOINed de TOP dans SQL Server?

Disons que j'ai deux tables de livres et deux tables de leurs éditions correspondantes.

J'ai une requête comme suit:

SELECT TOP 10 * FROM (SELECT hbID, hbTitle, hbPublisherID, hbPublishDate, hbedID, hbedDate FROM hardback LEFT JOIN hardbackEdition on hbID = hbedID UNION SELECT pbID, pbTitle, pbPublisher, pbPublishDate, pbedID, pbedDate FROM paperback Left JOIN paperbackEdition on pbID = pbedID ) books WHERE hbPublisherID = 7 ORDER BY hbPublishDate DESC 

S'il y a 5 éditions des deux premiers livres brochés et / ou livres de poche, cette requête renvoie seulement deux livres. Cependant, je veux que le TOP 10 s'applique uniquement au nombre d'loggings de livre réels returnnés. Y a-t-il un moyen de sélectionner 10 livres réels et d'get tous leurs loggings d'édition associés?

Dans le cas où cela est pertinent, je n'ai pas d'permissions de database pour créer et supprimer des tables temporaires.

Merci d'avoir lu!

Mettre à jour

Pour clarifier: La table de livre de poche a un tableau associé des éditions de livre de poche. La table de reliure a une table associée d'éditions reliées. Les tables de reliure et de livre de poche ne sont liées l'une à l'autre qu'à l'user qui les verra (on l'espère!) Les afficher set.

Pas si facile. Vous devez appliquer Top 10 uniquement aux tables de reliure et de livre de poche, sans la jointure. Puis joignez le résultat aux données.

La requête suivante ne fonctionne que lorsque hbID et pbID sont toujours uniques. Sinon, ça devient plus compliqué. Vous devez les séparer ou append une autre colonne à la requête pour les distinguer.

 SELECT * FROM (SELECT hbID as id, hbTitle, hbPublisherID, hbPublishDate, hbedID, hbedDate FROM hardback LEFT JOIN hardbackEdition on hbID = hbedID UNION SELECT pbID as id, pbTitle, pbPublisher, pbPublishDate, pbedID, pbedDate FROM paperback Left JOIN paperbackEdition on pbID = pbedID ) books INNER JOIN (SELECT TOP 10 * FROM (SELECT hbID as id, hbPublisherID as publishedId, hbPublishDate as publishDate FROM hardback UNION SELECT pbID as id, pbPublisherID as publishedId, pbPublishDate as publishDate FROM paperback ) WHERE publisherID = 7 ORDER BY publishDate DESC ) topTen on books.id = TopTen.id 

Si je vous comprends bien, vous pourriez get les 10 livres avec toutes les éditions associées par

  • Utilisation d'une instruction WITH pour renvoyer le jeu de résultats initial et complet
  • select 10 livres distincts en utilisant un GROUP BY
  • JOIN aux résultats de ce groupe pour conserver toutes les informations de 10 livres donnés.

Déclaration SQL

 ;WITH books AS ( SELECT hbID, hbTitle, hbPublisherID, hbPublishDate, hbedID, hbedDate FROM hardback LEFT JOIN hardbackEdition on hbID = hbedID WHERE hbPublisherID = 7 UNION ALL SELECT pbID, pbTitle, pbPublisher, pbPublishDate, pbedID, pbedDate FROM paperback LEFT JOIN paperbackEdition on pbID = pbedID WHERE hbPublisherID = 7 ) SELECT * FROM books b INNER JOIN ( SELECT TOP 10 hbID FROM books GROUP BY hbID ) bt ON bt.hbID = b.hbID 

ou si vous préférez écrire la clause where une seule fois

 ;WITH books AS ( SELECT hbID, hbTitle, hbPublisherID, hbPublishDate, hbedID, hbedDate FROM hardback LEFT JOIN hardbackEdition on hbID = hbedID UNION ALL SELECT pbID, pbTitle, pbPublisher, pbPublishDate, pbedID, pbedDate FROM paperback LEFT JOIN paperbackEdition on pbID = pbedID ) , q AS ( SELECT * FROM books WHERE hbPublisherID = 7 ) SELECT * FROM qb INNER JOIN ( SELECT TOP 10 hbID FROM q GROUP BY hbID ) bt ON bt.hbID = b.hbID 

Cela devrait saisir les dix derniers titres publiés avec un livre relié de l'éditeur 7:

 select * from ( select top 10 title from hardback where hbPublisherID = 7 group by title order by hbPublishDate desc ) top_titles left join hardback on hardback.hbTitle = top_titles.title left join paperback on paperback.pbTitle = top_titles.title