Sql Server - 动态排除记录

时间:2014-07-22 02:42:48

标签: sql-server-2008 tsql

我正在寻找一种基于appId动态排除记录的方法。

为此,我想到了:

1)创建一个名为tblExclude的表:

AppId | Field   | Value
----------------------
1     | email   |  John@aol.com
1     | email   |  Doe@aol.com
1     | Id      |  2
2     | Id      | 10

2)创建一个表值函数,根据AppId查询上面的表并动态生成sql并使用sqlexcute函数 该函数将生成sql看起来像这样并返回记录集:

Select Id  
from  Table1 
where  email in ('John@aol.com', 'Doe@aol.com') 
    or Id in (2)

3)程序看起来像下面的查询,但显然更复杂

   Select * 
   from  table1
   where [criterias]
   and not exists ( select Id
                    from udfExclude(1) e 
                    where e.Id = table1.Id

我并不为这个解决方案而疯狂,我想知道是否有人有更优雅的解决方案。

我使用的是sql server 2008 r2

感谢。

2 个答案:

答案 0 :(得分:0)

我会亲自把它作为两张桌子。除非表格也是动态的。

<强> AppIdExclusionEmails

AppId | Value
---------
1     |  John@aol.com
1     |  Doe@aol.com

<强> AppIdExclusionIds

AppId | Value
1     |  2
2     | 10

然后你可以写出来的问题

SELECT Id
FROM Table1
WHERE email NOT IN (SELECT Value FROM AppIdExclusionEmails WHERE AppId = @appid) AND
      Id NOT IN (SELECT Value FROM AppIdExclusionIds WHERE AppId = @appid)

这也为您提供了一些优势,例如ID值上的外键(如果适用)。更不用说强打字了​​。

如果您愿意,也可以将其作为一个表执行,只需拥有多个列,一个用于Email,一个用于Id,然后每个记录在一列中都有一个值{{1} 1}}在另一个。但这似乎比两张桌子更加混乱,更不用说空间效率更低了,而且添加一张桌子不需要花费任何费用。

答案 1 :(得分:0)

如果您知道要在email列中查找idField值,则可以使用以下查询:

declare @AppID int = 1   

delete from Table1 
where Id not in (
  select distinct ID
  from Table1 A
  inner join tblExclude B
    on AppID = @AppID
    and (A.email = case when Field = 'email' then Value else null end
    or A.Id = case when Field = 'id' then Value else null end)
  )

请查看SQL Fiddle