views:

53

answers:

3

I am trying to develop a T-SQL query to exclude all rows from another table "B". This other table "B" has 3 columns comprising its PK for a total of 136 rows. So I want to select all columns from table "A" minus those from table "B". How do I do this? I don't think this query is correct because I am still getting a duplicate record error:

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))
+3  A: 

use NOT EXISTS...NOT IN doesn't filter out 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)

Just so you know, take a look at Select all rows from one table that don't exist in another table

Basically there are at least 5 ways to select all rows from onr table that are not in another table

  • NOT IN
  • NOT EXISTS
  • LEFT and RIGHT JOIN
  • OUTER APLY (2005+)
  • EXCEPT (2005+)
SQLMenace
Thanks but something about this query is not correct because when I count rows from this query without this NOT EXISTS vs. with it, I am getting same number of rows returned.
salvationishere
The problem could be that one of those already exists in your J5C_MasterMeasures table..you are right now dumping into #b only the ones with more than 1 row..what if use Test is not in #B but is in [J5C_Measures_Sys] already? you will get a PK violation
SQLMenace
added another not exists clause that filters out the ones already in the J5C_MasterMeasures table
SQLMenace
A: 

I think you can use "NOT IN" with a subquery, but you say you have a multi-field key?

I'd be thinking about using a left outer join and then testing for null on the right...

Martin.

Martin Milan
The Not Exists is also a valid approach...Whilst "NOT IN" is no good to you in your particular case anyway, it is something generally best avoided unless you're dealing with a small set of data in the list you're testing. Behind the scenes the server builds a massive WHERE clause, and there can be limits on the size of that...
Martin Milan
Good points, Martin. Yes, this is a multi-field key.
salvationishere
+2  A: 

Here is a general solution for the difference operation using left join:

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

Of course yours would have a more complicated join on clause, but the basic operation is the same.

Ian Henry
I tried ur solution also and it was returning same number of rows and duplicate error still. Do u understand what might be the cause?
salvationishere
Without more information, no. If you update your question with the exact query you tried that didn't work I can take a look at it and possibly spot the problem.
Ian Henry