2009-12-03 4 views
1

je la requête suivante:Comment réparer cette requête SQL GROUP BY?

SELECT 
    dev.DeviceName, Count(dom.DomainID) AS CountOfDomains 
FROM 
    tblDevices dev 
JOIN 
    tblIPNumbers ip ON dev.DeviceName = ip.ServerName 
JOIN 
    tblDomains dom ON dom.IPNumberID = ip.IPNumberID 
WHERE 
    dom.PointerTo=0 
    AND dev.DeviceType='3' 
    AND (dev.[System]='32' OR dev.[System]='33') 
    AND dom.ClosedDate IS NULL AND dev.Active=1 
GROUP BY 
    dev.DeviceName 
ORDER BY 
    Count(dom.DomainID) 

Les tableaux ressemblent:

 
tblDomains 
========== 
DomainID  int 
IPNumberID  int 
ClosedDate  datetime 
PointerTo  int 

tblIPNumbers 
============ 
IPNumberID  int 
ServerName  varchar(200) 

tblDevices 
========== 
DeviceID  int 
DeviceName  varchar(200) 
System   varchar(10) 
DeviceType  varchar(10) 
Active   bit 

données Exemple:

 
tblDomains: 
=========== 
DomainID: 1234 IPNumberID: 1000 ClosedDate: NULL PointerTo: 0 

tblIPNumbers: 
============= 
IPNumberID: 1000 ServerName: WIN2008-01 

tblDevices: 
=========== 
DeviceID: 1 DeviceName: WIN2008-01  System: 32 Active: 1 DeviceType: 3 

Le problème est que s'il n'y a pas de lignes dans tblDomains qui correspondent à IPNumberID dans tblIPNumbers Je ne reçois aucune ligne retournée. Je voudrais que la requête renvoie une seule ligne de 0 pour Count(dom.DomainID) AS CountOfDomains dans ce cas.

J'ai essayé différentes combinaisons de jointures LEFT et RIGHT et cela semble être un problème simple, mais mon SQL-fu est faible aujourd'hui.

+0

Que se passe lorsque vous remplacez '' JOIN tollon.tblDomains' avec LEFT JOIN tollon.tblDomains'? –

Répondre

1

Vous devez utiliser LEFT JOIN s au lieu de JOIN s, et méfiez-vous aussi que lorsqu'un LEFT JOIN ne trouve pas une ligne correspondante dans la table de droite, il retournera NULL s pour tout champ de cette table droite.

Cela signifie que vous émettez vient de votre article WHERE qui fait référence à dom.pointerto de manière non NULL -safe, ce qui aura pour effet d'annuler les avantages du LEFT JOIN.

+0

Ah, oui, donc vous voudrez probablement spécifier 'WHERE (dom.pointerto = 0 OU dom.pointerto IS NULL) ...' –

+0

La combinaison de la réponse de PP et Romain a fonctionné. Merci les gens pour le travail rapide. – Kev

1

Modifiez vos JOIN s en LEFT JOIN et ils incluront également des enregistrements non correspondants.

+0

J'ai essayé mais ça ne marche malheureusement pas. – Kev

+0

vraiment? avez-vous une erreur, ou juste le même comportement que votre courant? –

+1

Il pense qu'il vient de la clause WHERE. Voir ma réponse;) – Romain

0

Essayez d'utiliser jointure externe pour la table tbldomains


SELECT 
    dev.DeviceName, Count(dom.DomainID) AS CountOfDomains 
FROM 
    tblDevices dev 
JOIN 
    tblIPNumbers ip ON dev.DeviceName = ip.ServerName 
outer JOIN 
    tblDomains dom ON dom.IPNumberID = ip.IPNumberID 
WHERE 
    dom.pointerto=0 
    AND dev.devicetype='3' 
    AND (dev.[System]='32' OR dev.[System]='33') 
    AND dom.ClosedDate IS NULL AND dev.active=1 
GROUP BY 
    dev.DeviceName 
ORDER BY 
    Count(dom.DomainID) 
+0

Astuce: ajoutez

...
autour de votre code pour faciliter la lecture –