从另一个表中筛选表

时间:2013-02-18 19:25:24

标签: sql-server tsql sql-server-2005

我在创建查询时遇到问题

===========      ============================         ================= 
ValueTable1      ValueTable2                          FilterTable1      
===========      ============================         ================= 
Id |Name         Id | RefNo || Property| Value        Id|Property|Operator|Value
 1 |X             1     1       P1         500         1   P1        >       100
                  2     1       P2         300         1   P2        =       300
                  3     1       P3         200         1   P3        <>      100

2  |Y             4     2       P1         250
                  5     2       P2         100
                  6     2       P3         200

我的数据库中有2个表ValueTable和1个过滤表 我想创建一个可以从FilterTable1中的属性和运算符过滤Valuetabl2的查询 我无法创造它。有什么办法吗?

3 个答案:

答案 0 :(得分:0)

例如,您必须在过程循环中为sql语句创建一个字符串,然后执行它。

请参阅此处如何执行:http://msdn.microsoft.com/de-de/library/ms188332.aspx

您无法直接创建动态SQL查询。

因此,创建一个过程,创建一个本地游标以循环到ValueTable2,并为每个属性检查operator中的FilterTable1,然后创建一个新的sql字符串,然后执行。

修改

我不完全理解你的要求,但这个例子应该给你一个方法:

DECLARE @operator varchar(2)
DECLARE @value varchar(255)
DECLARE @sql varchar(max)

DECLARE cur1 CURSOR FOR

SELECT [operator], CAST([value] AS varchar(255))
FROM ValueTable2 v
JOIN FilterTable1 f ON v.Property = f.Property

OPEN cur1

FETCH NEXT FROM cur1
INTO @operator, @value

WHILE @@FETCH_STATUS = 0
  BEGIN
  @sql = 'SELECT * FROM ValueTable2 WHERE [value] ' + @operator + ' ' + @value
  PRINT @sql
  -- EXEC sp_executesql @sql
  FETCH NEXT FROM cur1 INTO @operator, @value
END

DEALLOCATE cur1

答案 1 :(得分:0)

好吧,我会尽量不使用CURSORS和/或动态SQL。游标可能会产生严重的锁定问题,并且动态SQL总是被(重新)编译,所以在我的观点中这样做是不可能的。

但是,使用带有while循环的临时表可能更好,而不是游标。对于逻辑,我会说可以使用一些if语句..

我做了这个SQLFiddle(http://sqlfiddle.com/#!3/8a4e3/)来向你展示我的意思

答案 2 :(得分:0)

也许我误解了你的问题......

你想在FilterTable1上对表ValueTable2的值应用那些过滤器,对吗?

使用过滤器进行AND条件...

确定什么RefNo填补所有条件..我是对的?或者在这一点上被误解了?

并且这个RefNo引用了表ValueTable1,对吗?或者我误解了?

如果我做得不好

可以尝试这样的事情......

    create table ##ValueTable1 (id int , name varchar)
    insert into ##ValueTable1
    values (1,'X'),(2,'Y')

    create table ##ValueTable2 (id int , RefNo int, Property nvarchar(max),value int)
    insert into ##ValueTable2
    values 
    ( 1 ,   1  ,'P1',      500),
    ( 2 ,   1  ,'P2',      300),
    ( 3 ,   1  ,'P3',      200),
    ( 4 ,   2  ,'P1',      250),
    ( 5 ,   2  ,'P2',      100),
    ( 6 ,   2  ,'P3',      200)

    create table ##FilterTable1 (id int, Property nvarchar(max),Operator nvarchar(max) , value int)
    insert into ##FilterTable1
    values 
    (1,'P1','>', 100),
    (1,'P2','=', 300),
    (1,'P3','<>',100)




     declare @sql nvarchar(max)
     set @sql = ''
     select @sql = @sql + ' intersect  select RefNo from ##ValueTable2 where Property = ''' +Property+''' and value '+Operator+CAST(value as varchar(max))
     from ##FilterTable1 
     where id = 1
     set @sql = 'select * from ##ValueTable1 T inner join ('+STUFF(@sql,1,10,'') +')V on V.RefNo = T.id'
     --just stuff @sql if ##ValueTable1 doesnt matter
     --set @sql = STUFF(@sql,1,10,'')  

     exec(@sql)


    drop table ##ValueTable2
    drop table ##FilterTable1
    drop table ##ValueTable1

我的结果集是......

id  name    RefNo
1   X       1