左表有一个列名为Status,右表,只有一列Status。
现在用右表作为左标的Filter,也就是说只取左表中Status=右表Status的记录:SELECT *
FROM dbo.Mails AS L INNER JOIN @MailStatusFilters AS R ON (L.Status = R.Status)
当右表@MailStatusFilters为空表时,这时做内连接,返回的一定是一个空表。
我想实现相反的结果,即,当右表@MailStatusFilters为空表时(不指定Filter),返回整个左表,所有的Mail。
请问有什么办法可以实现?
谢谢。

解决方案 »

  1.   

    左表 left join 右表
      

  2.   

    谢谢,看起来左连接除了返回符合ON条件的行,还会返回左表的全部记录,这样不符合我的要求。我想实现的是:
    1, 当右表不为空,那末实现 INNER JOIN的语义(返回仅左表.status = 右表.status)的记录;
    2, 当右表为空,那末返回左表的全部记录。
      

  3.   


    SELECT *
    FROM dbo.Mails AS L LEFT JOIN @MailStatusFilters AS R ON (L.Status = R.Status)
      

  4.   


    create table aa(rowid int,status int)
    create table bb(rowid int,status int)insert into aa
    select 1,1 union all
    select 2,2 union all
    select 3,5SELECT *
    FROM aa AS L INNER JOIN bb AS R ON (L.Status = R.Status)
    WHERE exists(select 1 from bb)
    UNION ALL
    SELECT *
    FROM aa AS L LEFT JOIN bb AS R ON (L.Status = R.Status)
    WHERE not exists(select 1 from bb)/*
    rowid status rowid status
    1 1 NULL NULL
    2 2 NULL NULL
    3 5 NULL NULL
    */
    insert into bb
    select 3,1 union all
    select 4,2 union all
    select 3,3 union all
    select 4,4SELECT *
    FROM aa AS L INNER JOIN bb AS R ON (L.Status = R.Status)
    WHERE exists(select 1 from bb)
    UNION ALL
    SELECT *
    FROM aa AS L LEFT JOIN bb AS R ON (L.Status = R.Status)
    WHERE not exists(select 1 from bb)
    /*
    rowid status rowid status
    1 1 3 1
    2 2 4 2
    */
      

  5.   

    thanks,请问exists(select 1 from bb)意思是说,“第一列在表bb中存在”吗?
    我理解,第一个select语句:SELECT *
    FROM aa AS L INNER JOIN bb AS R ON (L.Status = R.Status)
    WHERE exists(select 1 from bb)
    的意思就是:将aa和bb作内连接(aa.status = bb.status),得到一个结果集,然后从结果集中选取bb.rowid不为空的那些列。对吗?
      

  6.   

    exists(select 1 from bb)意思是说,bb表中存在数据,不为空表
      

  7.   

    if exists(select 1 from tb2)
       select m.* , n.* from tb1 , tb2 where m.status = n.status
    else
       select m.* from tb1 m 
      

  8.   

    谢谢大家,这个功能我是打算放在FROM子句里面的,10楼的办法行不通。
      

  9.   

    谢了,这里1不是表示第一列?那表示什么?和exists(select * from bb)岂不是没有区别吗?
      

  10.   

    与空表就别做连接了.
    连接了不是浪费时间么?还得费劲写连接程序,直接
    select * from 非空表
    得了.
      

  11.   

    我也想这样,但是FROM子句里面不能动态决定到底要不要做inner join。我又不想弄一个巨大的if else。
      

  12.   

    你既然FROM前面的语句是不变的,那就一开始先判断右表是否为空,然后根据判断结果生成2种语句,再拼接到FROM后面去不就行了。这样判断也是个简单判断,代码又不要写很多。
      

  13.   


    declare @str varchar(4000)
            @from varchar(2000)
    set @str='select * from 左表 '
    if exists (select 1 from 右表)
    begin
        set @from=' a inner join 右表 b on a.Status=b.Status'
    end
    else
    begin
        set @from=''
    end
    set @str=@str+@from
    exec (@str)
      

  14.   

    SELECT L.*
    FROM aa AS L INNER JOIN bb AS R ON (L.Status = R.Status)
    UNION ALL
    SELECT L.*
    FROM aa AS L 
    WHERE not exists(select status from bb group by status having count(*)>=1)