2010-08-23 5 views
0

J'essaie de développer une requête T-SQL pour exclure toutes les lignes d'une autre table "B". Cette autre table "B" a 3 colonnes comprenant son PK pour un total de 136 lignes. Je veux donc sélectionner toutes les colonnes de la table "A" moins celles de la table "B". Comment puis-je faire cela? Je ne pense pas que cette requête est correcte parce que je reçois toujours une erreur d'enregistrement en double:Syntaxe pour SQL non dans la liste?

CREATE TABLE #B (STUDENTID VARCHAR(50), MEASUREDATE SMALLDATETIME, MEASUREID VARCHAR(50)) 
INSERT #B 
SELECT studentid, measuredate, measureid 
    from [J5C_Measures_Sys] 
GROUP BY studentid, measuredate, measureid 
    HAVING COUNT(*) > 1 

insert into J5C_MasterMeasures (studentid, measuredate, measureid, rit) 
select A.studentid, A.measuredate, B.measurename+' ' +B.LabelName, A.score_14 
from [J5C_Measures_Sys] A 
join [J5C_ListBoxMeasures_Sys] B on A.MeasureID = B.MeasureID 
    join sysobjects so on so.name = 'J5C_Measures_Sys' AND so.type = 'u' 
join syscolumns sc on so.id = sc.id and sc.name = 'score_14' 
join [J5C_MeasureNamesV2_Sys] v on v.Score_field_id = sc.name 
where a.score_14 is not null AND B.MEASURENAME IS NOT NULL 
and (A.studentid NOT IN (SELECT studentid from #B) 
and a.measuredate NOT IN (SELECT measuredate from #B) 
and a.measureid NOT IN (SELECT measureid from #B)) 

Répondre

3

utilisation NOT EXISTS ... PAS ne filtre pas NULLS

insert into J5C_MasterMeasures (studentid, measuredate, measureid, rit) 
select A.studentid, A.measuredate, B.measurename+' ' +B.LabelName, A.score_14 
from [J5C_Measures_Sys] A 
join [J5C_ListBoxMeasures_Sys] B on A.MeasureID = B.MeasureID 
    join sysobjects so on so.name = 'J5C_Measures_Sys' AND so.type = 'u' 
join syscolumns sc on so.id = sc.id and sc.name = 'score_14' 
join [J5C_MeasureNamesV2_Sys] v on v.Score_field_id = sc.name 
where a.score_14 is not null AND B.MEASURENAME IS NOT NULL 
AND NOT EXISTS (select 1 from #B where #b.studentid = A.studentid 
and a.measuredate = #B.measuredate 
and a.measureid = #B.measureid) 
    and not exists (select 1 from J5C_MasterMeasures z 
        where z.studentid = A.studentid) 

Juste pour que vous connaissez , jetez un oeil à Select all rows from one table that don't exist in another table

Fondamentalement, il y a au moins 5 façons de sélectionner toutes les lignes de la table de ONR qui ne sont pas dans une autre table

  • PAS
  • PAS EXISTE
  • gauche et droite REJOIGNEZ
  • EXTÉRIEUR aply (2005+)
  • SAUF (2005+)
+0

Merci, mais quelque chose à propos de cette requête n'est pas correct, car lorsque je compte les lignes de cette requête sans que ce soit NOT EXISTS par rapport à cela, je reçois le même nombre de lignes retournées. – salvationishere

+0

Le problème pourrait être que l'un d'entre eux existe déjà dans votre table J5C_MasterMeasures ... vous êtes en train de déverser dans #b seulement ceux qui ont plus de 1 rang..what si utilisation Test n'est pas dans #B mais est dans [J5C_Measures_Sys] déjà? vous obtiendrez une violation PK – SQLMenace

+1

ajouté une autre clause inexistante qui filtre ceux déjà dans la table J5C_MasterMeasures – SQLMenace

0

Je pense que vous pouvez utiliser "NOT IN" avec sous-requête, mais vous dites que vous avez une clé multi-champs?

Je penserai à l'aide d'une jointure externe gauche et ensuite tester pour null à droite ...

Martin.

+0

Le Not Exists est également une approche valide ... Alors que "NOT IN" n'est pas bon pour vous dans votre cas particulier Quoi qu'il en soit, il vaut généralement mieux éviter cela, sauf si vous avez affaire à un petit ensemble de données dans la liste que vous testez. Dans les coulisses, le serveur construit une clause WHERE massive, et il peut y avoir des limites sur la taille de ce ... –

+0

Bons points, Martin. Oui, c'est une clé multi-champs. – salvationishere

2

Voici une solution générale pour l'opération de différence à l'aide left join:

select * from FirstTable 
left join SecondTable on FirstTable.ID = SecondTable.ID 
where SecondTable.ID is null 

Bien sûr la vôtre aurait une clause join on plus compliquée, mais le fonctionnement de base est le même.

+0

J'ai essayé votre solution aussi et il retournait le même nombre de lignes et l'erreur de duplicata encore. Comprenez-vous quelle pourrait être la cause? – salvationishere

+0

Sans plus d'informations, non. Si vous mettez à jour votre question avec la requête exacte que vous avez essayée et qui n'a pas fonctionné, je peux y jeter un coup d'œil et éventuellement repérer le problème. –