Merci de m'avoir aidé à trouver une solution à ce SQL que je n'arrive pas à comprendre.
Dans mon instruction SQL, j'ai 1 jointure interne et 1 jointure externe. L'une des sommations nécessite un décompte des lignes renvoyées par une jointure interne
SELECT
T3.Location AS Location,
T3.Date AS [Date],
SUM(T1.Column3- (T2.Column3+ T2.Column4)) as Result_Numerator,
SUM(T1.Column4 - COUNT(T2.Column2)) AS Result_Denominator,
SUM(T3.Column3 - T3.Column4) as Plan_Numerator,
SUM(T3.Column4 - T3.Column3) as Plan_Denominator,
'Element Name' as Element
FROM Table1 T1
INNER JOIN
Table2 T2 ON T1.Date= T2.Date AND T1.Location = T2.Location
RIGHT OUTER JOIN
Table3 T3 ON T1.Date = T3.DATE and T3.Location = P.Location
WHERE T1.Location = '1' AND (T3.Date>({ts '2019-11-01 00:00:00'}))
AND T3.Column5 = '0' AND T2.Column3>0 AND T2.Column5 ('05','06')
GROUP BY T3.Location,
T1.CNY_CD,
T3.PLN_DATE,
Ma déclaration incorrecte, avec la nécessité du décompte à la ligne 5
Table 1 Location |Date |Column3 |Column4 1 |11/22/2019 |23 |3 2 |11/22/2019 |23 |4 3 |11/22/2019 |12 |5 4 |11/22/2019 |54 |6 5 |11/22/2019 |65 |7 6 |11/22/2019 |23 |8 7 |11/22/2019 |5 |9 Table 2 Location |Date |Column3 |Column4 |Column5 1 |11/22/2019 |1 |8.5 |06 1 |11/22/2019 |2 |8.5 |06 1 |11/22/2019 |3 |8 |06 1 |11/22/2019 |4 |8.5 |06 2 |11/22/2019 |5 |7.5 |06 2 |11/22/2019 |5 |8.5 |06 2 |11/22/2019 |6 |8.5 |06 Table 3 Location |Date |Column3 |Column4 |Column5 1 |11/22/2019 |3 |3 |1 2 |11/22/2019 |4 |4 |0 3 |11/22/2019 |6 |5 |1 4 |11/22/2019 |25 |6 |0 5 |11/22/2019 |65 |7 |1 6 |11/22/2019 |65 |8 |0 7 |11/22/2019 |78 |9 |1
J'ai regardé quelques-unes des questions similaires et ils suggèrent d'utiliser union all pour obtenir le décompte en premier, mais je ne comprends pas tout à fait comment faire fonctionner cela avec la jointure interne entre T1 et T2 .
Merci d'avance de m'avoir aidé D
3 Réponses :
RIGHT JOIN est déroutant. Utilisez plutôt une jointure à gauche.
Table2 peut également nécessiter une jointure à gauche.
Mais alors, les critères de Table2 devraient tous être dans ON, pas dans la clause WHERE. Ou il se comporterait comme un INNER JOIN.
...
FROM Table3 T3
LEFT JOIN Table2 T2
ON T2.Date= T3.Date
AND T2.Location = T3.Location
AND T2.Column3 > 0
AND T2.Column5 IN ('05','06')
LEFT JOIN Table1 T1
ON T1.Date = T3.Date
AND T1.Location = T3.Location
WHERE T3.Location = '1'
AND T3.Date >= CAST('2019-11-01' AS DATE)
AND T3.Column5 = '0'
GROUP BY T3.Location, T3.Date
Select SUM(...) as inner_sum from Table1 inner join Table2 on Table2.Date = Table1.Date and Table2.location = Table1.location UNION Select SUM(...) as outer join ....
Est-ce que cela me permettra d'utiliser la fonction Count dans la somme sur la ligne 5?
Oui, cela devrait, car d'après ce que je comprends, le problème que vous rencontrez est d'obtenir d'abord la somme de la jointure interne, puis la somme de la jointure externe, n'est-ce pas?
Vous n'avez pas montré de résultat attendu dans votre requête et vous ne nous avez pas dit quelles sont les clés des tables. Je suppose les clés suivantes:
Il semble également (mais je me trompe peut-être) que vous vouliez une ligne de résultat par lieu et par date. Cela signifie que vous devez agréger les données de la table 2.
Je ne sais pas quelles données de table sont obligatoires dans votre requête et lesquelles ne le sont pas. Il semble que vous souhaitiez sélectionner dans la table3, qui peut ou non avoir des correspondances dans table1 et table2.
Beaucoup d'hypothèses, car votre requête ne dispose pas de toutes ces informations. Veuillez décrire vos tables, leurs relations et le résultat souhaité plus correctement la prochaine fois.
with t2 as
(
select location, date, sum(column3) as sum3, sum(column4) as sum4, count(*) as cnt
from table2
where column3 > 0 and column5 in ('05', '06')
group by location, date
)
select
t3.location,
t3.date,
t1.column3- (t2.sum3 + t2.sum4) as result_numerator,
t1.column4 - t2.cnt as result_denominator,
t3.column3 - t3.column4 as plan_numerator,
t3.column4 - t3.column3 as plan_denominator
from table3 t3
left join table1 t1 on t1.location = t3.location and t1.date = t3.date
left join t2 on t2.location = t3.location and t2.date = t3.date
where t3.location = 1 and t3.date >= '2019-11-02' and t3.column5 = 0
order by t3.location, t3.date;
Avec toutes ces suppositions, vous devrez peut-être ajuster cette requête, mais vous voyez l'idée.
Juste une remarque: j'ai utilisé une clause WITH ici pour la lisibilité, mais vous pouvez tout aussi bien mettre la requête d'agrégation dans votre clause FROM , si vous aimez mieux ceci: jointure gauche (.
Merci pour ce qui précède, j'essaie de revoir et de comprendre ce qui se passe. en réponse à votre question, il n'y a pas de clé de relation entre les tables. Le tableau 3 ne fait que s'additionner par rapport à lui-même car il s'agit de données de plan. Le principal problème que j'ai est de faire fonctionner le décompte.
Je ne comprends pas encore exactement ce que vous voulez sélectionner. Pouvez-vous montrer le résultat souhaité s'il vous plaît? Et quelles sont les clés des tables? S'agit-il de
Locationà la fois pourtable1ettable3?Quel est votre SGBD au fait? MySQL? Serveur SQL? ...
J'utilise SQL Server
Mon résultat souhaité en utilisant l'emplacement 1 comme exemple serait Location = 1 Date = 22/11/2019 Result_Denominator = 3-4
Sans savoir quelles sont les clés des tables, je ne peux que deviner de quelle requête il s'agit exactement. Mais il me semble évident que la solution à votre problème est que vous devez d'abord agréger ce qui doit être agrégé et ensuite seulement rejoindre. J'ai posté une réponse le montrant.