Jointure externe ou une requête dynamique, ce qui est la meilleure façon d'aller?
-
18-09-2019 - |
Question
Je les tableaux ci-dessous (je l'ai simplifié les données contenues dans les tableaux).
RateTable
- rate_table_id [int]
- rate_table_name [nvarchar(50)]
RateTableUsed
- rate_used_id [int]
- rate_table_id [int] (key to RateTable.rate_table_id)
- customer_id [int]
RateTableExtra
- rate_table_extra_id [int]
- rate_ extra_id [int] (key to RateExtra.rate_table_id)
- rate_used_id [int] (key to RateTableUsed.rate_used_id)
RateExtra
- rate_ extra_id [int]
- rate_extra_name [nvarchar(50)]
select rate_table_name, rate_table_extra_id, rate_extra_name from RateTableUsed rtu
innerjoin RateTable rt on rtu.rate_table_id = rt.rate_table_id
innerjoin RateTableExtra rte on rte.rate_table_id = rt.rate_table_id
innerjoing RateExtr re on rte.rate_extra_id = re.rate_extra_id
Le RateExtra ne contient que 3 valeurs avec clé de 1, 2 et 3 et la surcharge de l'essence de noms, des frais de gestion et de la TPS.
Cela fonctionne très bien pour son but actuel. Une liste de valeurs est affichée avec les enregistrements correspondants et RateExtra est interrogé uniquement pour le rate_extra_name.
Alors, je peux avoir les résultats suivants:
- Ratetable1, 1, PetrolSurcharge
- Ratetable1, 2, ManagementFee
- Ratetable2, 3, PetrolSurcharge
- Ratetable4, 4, TPS
- Ratetable6, 5, PetrolSurcharge
On m'a demandé de modifier cette façon que chaque enregistrement qui retourne comprend maintenant les enregistrements pour chaque valeur dans le tableau RateExtra. S'il n'y a aucun enregistrement correspondant alors les données de ma table de RateTableExtra devrait revenir NULL. Donc, mes données devraient revenir comme:
- Ratetable1, 1, PetrolSurcharge
- Ratetable1, 2, ManagementFee
- Ratetable1, NULL, TPS
- Ratetable2, 3, PetrolSurcharge
- Ratetable2, NULL, ManagementFee
- Ratetable2, NULL, TPS
- Ratetable4, NULL, PetrolSurcharge
- Ratetable4, NULL, ManagementFee
- Ratetable4, 4, TPS
- Ratetable6, 5, PetrolSurcharge
- Ratetable6, NULL, ManagementFee
- Ratetable6, NULL, TPS
Je l'ai essayé jointures OUTER mais ils ne semblent pas fonctionner Je suppose parce que les données RateExtra est liée à la RateTableExtra qui retourne NULL. J'envisage maintenant la création d'une requête dynamique qui va obtenir mon jeu original résultat, itérer dessus pour vérifier rate_extra_id et, si elle est pas déjà dans le resultset, ajoutant une nouvelle ligne aux résultats avec les données NULL où je en ai besoin. Je suppose que cela fonctionnerait, mais j'ai le sentiment que ce serait un tueur sur la performance.
Y at-il une meilleure façon de le faire? Espérons que quelqu'un peut aider, ce serait vraiment apprécié.
La solution
Essayez ceci:
select
rate_table_name,
rate_table_extra_id,
rate_extra
from
RateTableUsed rtu
inner join RateTable rt on
rtu.rate_table_id = rt.rate_table_id
cross join RateExtra re
left outer join RateTableExtra rte on
rte.rate_table_id = rt.rate_table_id
and rte.rate_extra_id = re.rate_extra_id
order by rt.rate_table_name, re.rate_extra_id
Qu'est-ce que vous obtenez avec cette requête est, essentiellement, une jointure cartésienne entre RateTable
et RateExtra
, avec un left join
pour trouver les valeurs de RateTableExtra
qui correspondent à ces paires. Pour l'essentiel, cette requête ramène possible combinaisons de RateTable
et RateExtra
, et vous montrer ceux que vous avez dans votre table RateTableExtra
rapidement.
Soyez prudent avec joint cartésien. Ils peuvent sortir de la main très rapidement avec des tables de taille raisonnable! Amusez-vous!