【问题标题】:Syntax for SQL Not In List?SQL 的语法不在列表中?
【发布时间】:2011-04-02 17:41:48
【问题描述】:

我正在尝试开发一个 T-SQL 查询来排除另一个表“B”中的所有行。这个另一个表“B”有 3 列,包括它的 PK,总共 136 行。所以我想选择表“A”中的所有列减去表“B”中的列。我该怎么做呢?我认为这个查询不正确,因为我仍然收到重复记录错误:

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))

【问题讨论】:

    标签: tsql subquery not-exists


    【解决方案1】:

    使用NOT EXISTS...NOT IN 不会过滤掉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)
    

    你知道吗,看看Select all rows from one table that don't exist in another table

    基本上有至少5种方法可以从onr表中选择不在另一个表中的所有行

    • 不在
    • 不存在
    • 左和右连接
    • 外部应用 (2005+)
    • 除了(2005 年以上)

    【讨论】:

    • 谢谢,但是关于这个查询的一些事情是不正确的,因为当我从这个查询中计算行时没有这个 NOT EXISTS 与它,我得到相同数量的返回行。
    • 问题可能是其中一个已经存在于您的 J5C_MasterMeasures 表中..您现在只将超过 1 行的那些转储到 #b 中..如果使用测试不在 # B 但已经在 [J5C_Measures_Sys] 中了吗?你会得到一个PK违规
    • 添加了另一个不存在的子句,过滤掉 J5C_MasterMeasures 表中已经存在的子句
    【解决方案2】:

    这里是使用left join进行差分运算的一般解决方案:

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

    当然你的会有一个更复杂的join on子句,但基本操作是一样的。

    【讨论】:

    • 我也尝试了你的解决方案,但它仍然返回相同数量的行和重复错误。你知道可能是什么原因吗?
    • 没有更多信息,没有。如果您使用您尝试过但不起作用的确切查询更新您的问题,我可以查看它并可能发现问题。
    【解决方案3】:

    我认为您可以在子查询中使用“NOT IN”,但您说您有一个多字段键?

    我正在考虑使用左外连接,然后在右侧测试 null...

    马丁。

    【讨论】:

    • The Not Exists 也是一种有效的方法......虽然“NOT IN”在你的特定情况下对你没有好处,但通常最好避免这种情况,除非你正在处理一个小集合您正在测试的列表中的数据。服务器在幕后构建了一个巨大的 WHERE 子句,并且该子句的大小可能会受到限制......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 2018-06-05
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多