2017-08-04 5 views
1

J'ai deux tables que je souhaite joindre pour créer une table finale.Combiner deux tables dont le nombre de lignes est différent dans le serveur SQL

Query 1

select DisplayName, Category, NoOfLevels 
, count(Underoverestimate) as OverCount 
, Avg(CaseDuration - EstDuration) as ODA 
from DSU 
where yearid between '2016' and '2018' 
and underoverestimate = 'Over' 
group by DisplayName, Category, nooflevels 

Query 2

select DisplayName, Category, NoOfLevels 
, count(Underoverestimate) as UnderCount 
, Avg(CaseDuration - EstDuration) as ODA 
from DSU 
where yearid between '2016' and '2018' 
and underoverestimate = 'Under' 
group by DisplayName, Category, nooflevels 

requête 1 Résultats

DisplayName|Category  |NoOfLevels|OverCount|ODA 
Bran, J. |Fusion  |Single |2  |102.5 
Bran, J. |Decompression|   |1  |13 
Caron, M. |Fusion  |Multi  |9  |88.444 

requête 2 Résultats

DisplayName|Category  |NoOfLevels|UnderCount|ODA 
Curry, S. |Fusion  |Multi  |2  |105 
Bran, J. |Fusion  |Single |1  |115.5 
Bran, J. |Decompression|   |4  |131 
Caron, M. |Decompression|   |5  |66 

Ce que je veux que le résultat final soit de conserver tous DisplayName, Catergory et NoOfLevels uniques, mais ajouter 'OverCount' et ODA de la requête 1 et 'UnderCount' et 'ODA' de la requête 2.

DisplayName|Category  |NoOfLevels|OverCount|ODA |UnderCount|ODA 
Bran, J. |Fusion  |Single |2  |102.5 |1   |115.5 
Bran, J. |Decompression|   |1  |13  |4   |131 
Caron, M. |Decompression|   |   |  |5   |66 
Caron, M. |Fusion  |Multi  |9  |88.444 |   | 
Curry, S. |Fusion  |Multi  |   |  |5   |66 

J'ai essayé de le faire en faisant des tables temporaires avec requête 1 et 2, puis de faire une nouvelle déclaration de sélection pour signaler les données que je veux.

Select #QueryOne.DisplayName, #QueryOne.Category, 
#QueryOne.NoOfLevels, count(#QueryTwo.UnderCount) as UnderCount 
from #QueryOne 
join #QueryTwo 
on #QueryOne.DisplayName = #QueryTwo.DisplayName 
group by #QueryOne.DisplayName, #QueryOne.Category, 
#QueryOne.NoOfLevels 
order by #QueryOne.DisplayName, #QueryOne.Category, 
#QueryOne.NoOfLevels 

Mes résultats sont faux. (Je suis toujours tester la requête, donc je ne mentionnaient pas toutes les colonnes que je voulais encore, mais dans les tests, j'ai remarqué les résultats sont erronés)

DisplayName|Category  |NoOfLevels|UnderCount| 
Bran, J. |Fusion  |Single |6   | 
Caron, M. |Fusion  |Multi  |9   | 
Bran, J. |Decompression|   |6   | 
Curry, S. |Fusion  |Multi  |12  | 
Caron, M. |Decompression|   |9   | 

Les 3 premières colonnes semblent corrects, mais le sous-dénombrement ' les valeurs sont incorrectes. La fonction "COUNT" dans cette requête me donne un nombre total de lignes de Bran. L'utilisation de 'SUM' entraîne également de mauvaises informations. Et enfin, si je retire « COUNT (» alors je dois mettre # QueryTwo.UnderCount dans le groupe qui me donne les résultats suivants:

DisplayName|Category  |NoOfLevels|UnderCount| 
Bran, J. |Fusion  |Single |1   | 
Bran, J. |Fusion  |Single |2   | 
Bran, J. |Decompression|   |1   | 
Bran, J. |Decompression|   |2   | 
Caron, M. |Decompression|   |3   | 
Caron, M. |Decompression|   |2   | 
Caron, M. |Fusion  |Multi  |3   | 
Caron, M. |Fusion  |Multi  |1   | 

J'ai essayé de chercher cette réponse par stackoverflow mais havre de paix » J'ai trouvé un problème similaire, j'ai trouvé beaucoup de questions qui demandent de joindre deux tables, mais leurs problèmes ne sont pas les mêmes ... J'ai considéré UNION mais je ne peux pas sembler envelopper ma tête si c'est la prochaine étape. une partie du problème est que la requête 1 a DisplayNames qui ne sont pas dans la requête 2 et vice versa.Il est difficile de rejoindre?

Si je dois clarifier plus, s'il vous plaît faites le moi savoir, mon cerveau est bouillie.

Répondre

2

Essayez d'utiliser un full join pour obtenir toutes DisplayName unique Catégorie, les lignes de NoOfLevels des deux tables

select * 
from (query1) t1 
full join (query2) t2 
    on t1.DisplayName = t2.DisplayName 
    and t1.Category = t2.Category 
    and t1.NoOfLevels = t2.NoOfLevels 

Une autre solution possible consiste à utiliser l'agrégation conditionnelle sans joints

select DisplayName, Category, NoOfLevels 
, count(case when underoverestimate = 'Over' then Underoverestimate end) as OverCount 
, count(case when underoverestimate = 'Under' then Underoverestimate end) as UnderCount 
, Avg(case when underoverestimate = 'Over' then CaseDuration - EstDuration end) as ODA 
, Avg(case when underoverestimate = 'Under' then CaseDuration - EstDuration end) as UDA 
from DSU 
where yearid between '2016' and '2018' 
and underoverestimate IN ('Over' , 'Under') 
group by DisplayName, Category, nooflevels 
+1

J'aime la deuxième solution plus :) – BICube

+0

La première requête fournit toutes les informations nécessaires que je voulais, cependant, il devient difficile de sélectionner des colonnes spécifiques car il y a quelques displayNames dans t1 et d'autres en t2, l'utilisation de t1.displaynames ne présente pas toutes les combinaisons.Cependant, la deuxième requête que vous avez présentée fonctionne parfaitement! J'ajouterai ce processus de pensée à mon travail précédent! Je vous remercie! – MartyB

0

Vous pouvez utiliser pleinement rejoindre pour obtenir les résultats des deux tables. Pour plus d'informations, visitez s'il vous plaît https://www.w3schools.com/sql/sql_join_full.asp

SELECT 
    * 
FROM (SELECT 
    DisplayName, 
    Category, 
    NoOfLevels, 
    COUNT(Underoverestimate) AS OverCount, 
    AVG(CaseDuration - EstDuration) AS ODA 
FROM DSU 
WHERE yearid BETWEEN '2016' AND '2018' 
AND underoverestimate = 'Over' 
GROUP BY DisplayName, 
     Category, 
     nooflevels) a 
FULL OUTER JOIN (SELECT 
    DisplayName, 
    Category, 
    NoOfLevels, 
    COUNT(Underoverestimate) AS UnderCount, 
    AVG(CaseDuration - EstDuration) AS ODA 
FROM DSU 
WHERE yearid BETWEEN '2016' AND '2018' 
AND underoverestimate = 'Under' 
GROUP BY DisplayName, 
     Category, 
     nooflevels) b 
    ON a.DisplayName = b.DisplayName 
    AND a.Category = b.Category 
    AND a.NoOfLevels = b.NoOfLevels