A表:NAME AddRess NUM
a 北京 1
b 上海 70
c 天津 2
d 长春 5
B表:NAME AddRess
d 长春
a 北京
c 天津
d 长春
e 石家庄
a 北京
d 长春
c 天津
a 北京
e 石家庄
d 长春
c 天津要求:取出A表中的所有符合条件的记录,这个条件就是在B表中出现的次数小于A表中的对应的NUM字段值。比如,最终的结果应该是:NAME AddRess NUM
b 上海 70
d 长春 5
这样的SQL如何写? (我仅举例而已,实际的表数据量比较大,最好是比较优化的SQL语句) 。

解决方案 »

  1.   


    --> 测试数据:[A表]
    if object_id('[A表]') is not null 
    drop table [A表]
    create table [A表](
    [NAME] varchar(1),
    [AddRess] varchar(4),
    [NUM] int
    )
    insert [A表]
    select 'a','北京',1 union all
    select 'b','上海',70 union all
    select 'c','天津',2 union all
    select 'd','长春',5
    go
    --> 测试数据:[B表]
    if object_id('[B表]') is not null 
    drop table [B表]
    create table [B表](
    [NAME] varchar(1),
    [AddRess] varchar(6)
    )
    insert [B表]
    select 'd','长春' union all
    select 'a','北京' union all
    select 'c','天津' union all
    select 'd','长春' union all
    select 'e','石家庄' union all
    select 'a','北京' union all
    select 'd','长春' union all
    select 'c','天津' union all
    select 'a','北京' union all
    select 'e','石家庄' union all
    select 'd','长春' union all
    select 'c','天津'
    go
    create clustered index name_add_A_idx on [A表](NAME,[AddRess])
    go
    create clustered index name_add_B_idx on [B表](NAME,[AddRess])
    go
    with t
    as(
    select 
    [NAME],[AddRess],COUNT(1) as num
    from [B表]
    group by [NAME],[AddRess]
    )
    select * from [A表] a
    where not exists(select 1 from t 
    where a.[AddRess]=t.[AddRess] and a.NAME=t.NAME and a.NUM<t.num)
    go/*
    NAME AddRess NUM
    b 上海 70
    d 长春 5
    */--我记得你发过一个同样的帖子,我加了索引,给你看一下执行计划图:
      

  2.   

    select B.* from
    (
    select 
    [NAME],
    [AddRess],
    num = count(1)
    from [B表]
    group by [NAME],[AddRess]
    ) A
    inner join dbo.A表 B
    on A.[NAME] = B.[NAME]
    and A.[AddRess] = B.[AddRess]
    and A.num < B.num
    -- NAME,AddREss 建立索引