2010-12-09 4 views
1

Je suis un peu bogué pour savoir pourquoi ces deux constructions SQL ne donnent pas le même résultat.sql join -vs- where clause ne produisant pas le même résultat?

SQL # 1 retour 2 enregistrements identiques (DUP) quand une seule existe dans la table des défauts ... Voir l'image suivante sql

SELECT * 
FROM Defects d 
    JOIN StatusCode C ON C.CodeName = d.Status AND c.scid = 10 
WHERE d.AssignedTo='me' 

SQL # 2 rediffusions 1 enregistrement - c'est correcte Cause lookign à données brutes il y a un défaut pas fermé pour « moi »

SELECT * 
FROM Defects d 
WHERE d.AssignedTo='me' AND Status <> 'closed' 

tout ce que je suis en train de faire est au lieu d'utiliser un négatif où l'état non quelque chose, en utilisant un effet positif au moyen de la joindre aux dossiers qui ont chaque valeur état de défaut autre que fermé

pourquoi cela se produit-il, et comment puis-je modifier mon select avec la jointure pour corect le résultat. i essayé d'utiliser DISTINCT mais il échoue avec:

Le type de données ntext ne peut pas être sélectionné comme DISTINCT parce qu'il n'est pas comparable.

il n'y a pas de codes d'état qui sont 'fermés', et non un seul:

select * from StatusCode where scid = 10 

résultats dans ces valeurs: fixe Nouveau Prêt pour retest Échec retest Qualité Suivi rouvrez Rejeté consommation Dans le codage Ouvrir fixe Nouveau Prêt pour retest Échec retest Qualité Suivi Rouvrez Rejeté consommation Dans le codage Ouvrir

+1

Je vois que vous avez des champs ntext dans votre base de données. Vous devez commencer à les remplacer par nvarchar (max) car ntext est obsolète et ne sera plus dans la prochaine version de SQL Server après 2008. – HLGEM

Répondre

1

La jointure interne retournera toutes combinaisons de correspondance de lignes, il doit y avoir deux lignes de la table StatusCode qui correspondent à la valeur « Status » de votre Defect (et ont SCID = 10).

fixe
Nouveau
Prêt pour retest
Échec retest
Qualité Suivi
Rouvrez
Rejeté consommation
Dans le codage
Ouvrir
fixe
Nouveau
Prêt pour retest
Échec retest
Qualité Suivi
Rouvrez
Rejeté consommation
En Codage
Ouvrir

Vous ne savez pas si j'ai analysé votre liste? exactement exact, mais il semble y avoir des doublons. La réponse consiste donc soit à éliminer les doublons dans la table StatusCode, soit à appliquer un filtre supplémentaire pour les distinguer si les doublons sont valides.

+0

vous avez raison, donc ma pensée sql était correcte et les données étaient en faute pour l'erreur. bonne prise. merci un million! – kacalapy

1

Combien de lignes sont renvoyées par là?

SELECT * FROM StatusCode C WHERE c.scid = 10 

Vous pouvez donc faire ceci:

SELECT * 
FROM Defects d 
WHERE d.AssignedTo='me' AND d.Status IN (
    SELECT C.CodeName FROM StatusCode C WHERE C.scid = 10 
) 

Modifier pour traiter votre edit: puisque vous avez plusieurs états avec scid=10, chacun de ceux-ci seront jointes à vos lignes, ce qui est pourquoi vous obtenez les doublons. Ma suggestion de code est toujours valide.

+0

L'utilisation de l'IN est la même chose que faire une jointure pour éliminer les enregistrements indésirables, n'est-ce pas? c'est-à-dire que vous pouvez utiliser un IN ('Fixed', 'New', 'Ready for Retest' ...) pour obtenir un résultat qui exclut les défauts où le statut <> AKA fermé où status = toutes les options autres que closed. ainsi que se joindre au même ensemble pour obtenir une exclusion. – kacalapy

+0

Le 'JOIN 'va créer toutes les combinaisons correspondantes, ce qui n'est pas ce que vous voulez. Le 'IN' d'une part, juste comme un autre prédicat' WHERE' et retournera vrai si la valeur spécifiée est contenue dans l'ensemble 'IN()'. – Lucero

-2

Je pense que le problème est ici:

JOIN StatusCode C ON C.CodeName = d.Status AND c.scid = 10 

Le c.scid = 10 devrait être dans la clause where.

+1

Ceci est parfaitement valide en tant que condition de jointure, et comme il s'agit d'une jointure interne, cela signifie que les conditions non remplies ignorent la ligne, ce qui est (dans ce cas particulier) identique à la clause WHERE. – Lucero