没有动态sql的动态条件

时间:2014-11-20 09:06:50

标签: sql sql-server sql-server-2008 tsql

我有两张桌子

KeyWord Table
    | KeyWord1   |    Operator |     KeyWord2 |
    | -----------|------------:|:------------:|
    | Tom        |       AND   |     Harry    |
    | Krishna    |       OR    |     Radha    |
    | Raju       |       AND   |     Radha    |

Text Table

    | Id         |       Text                     |
    | -----------|-------------------------------:|
    | 1          |       Tom and Harry Nice       |
    | 2          |       Tom Harry Raju Radha Nice|
    | 3          |       Raju Radha Tom Nice      |

预期结果是

结果

    | Id         |       Text                     |
    | -----------|-------------------------------:|
    | 2          |       Tom Harry Raju Radha Nice|

结果是因为(Tom AND Harry) AND (Krishna OR Radha) AND (Raju AND Radha)。我需要使用LIKE运算符(LIKE '%'+tbl.Text+'%')来获取布尔表达式。

如果没有非动态sql方法,请告诉我最好的动态sql方法。

2 个答案:

答案 0 :(得分:1)

以下工作没有动态SQL或游标/ while循环。关于它的几点说明:

  • 由于“text”是一个保留字,我改名为:
    • [文本]表格为[TheText]
    • [文本]字段为[TheText]
  • 它使用相关的NOT EXISTS来抛出无效记录。这是因为:
    • 所有“关键字”集都是“AND”编辑在一起,因此它们必须都是真的
      • 他们必须都是真的,因此任何一个假的都会使记录无效
      • 如果我们只在NOT
      • 前面加EXISTS,那么单个错误条件会给出与所有正确条件相同的答案。
      • 更容易找到一个不匹配,而不是确保所有测试用例都匹配
      • 因为我们正在寻找条件的反向/反向(如关键字表中所述),我们通过以下方式反转AND / OR逻辑:
        • True AND True =>不正确或不正确
        • True OR True =>不是真的而不是真的
  • 测试数据中设置的OR条件不是一个好的测试,因为它具有一个AND条件集(即Radha)所需的值,因此不需要OR设置,无法确定逻辑是否适用于ANDOR条件。所以:
    • 我将名称Radha更改为Bob
    • 我在[TheText]中添加了Krishna的第4行,这是唯一应该(并且确实!)匹配的行

代码:

DECLARE @TheText TABLE (ID INT, TheText NVARCHAR(500));
INSERT INTO @TheText VALUES (1, N'Tom and Harry Nice');
INSERT INTO @TheText VALUES (2, N'Tom Harry Raju Radha Nice');
INSERT INTO @TheText VALUES (3, N'Raju Radha Tom Nice');
INSERT INTO @TheText VALUES (4, N'Tom Harry Raju Radha Krishna Nice');

DECLARE @Keywords TABLE (
  Keyword1 NVARCHAR(100) NOT NULL,
  Operator NVARCHAR(10) NOT NULL,
  Keyword2 NVARCHAR(100) NOT NULL
);
INSERT INTO @Keywords VALUES ('Tom', 'AND', 'Harry');
INSERT INTO @Keywords VALUES ('Krishna', 'OR', 'Bob');
INSERT INTO @Keywords VALUES ('Raju', 'AND', 'Radha');

SELECT *
FROM   @TheText txt
WHERE NOT EXISTS (
           SELECT *
           FROM   @Keywords kw
           WHERE  (
                      kw.Operator = N'AND'
                AND   (
                         txt.TheText NOT LIKE N'%' + kw.Keyword1 + N'%'
                  OR     txt.TheText NOT LIKE N'%' + kw.Keyword2 + N'%'
                      )
                  )
           OR     (
                      kw.Operator = N'OR'
                AND   (
                         txt.TheText NOT LIKE N'%' + kw.Keyword1 + N'%'
                  AND    txt.TheText NOT LIKE N'%' + kw.Keyword2 + N'%'
                      )
                  )
          );

结果:

ID  TheText
4   Tom Harry Raju Radha Krishna Nice

答案 1 :(得分:0)

我不确定,没有动态SQL还有其他方法可做。 尝试下面的代码,这肯定会帮助你。我在sybase中尝试过它很棒!



--Create Sample Tables
--Keyword Table
create table #tempKeyword
(col_id numeric(5,0) identity , Keyword1 varchar(100),Operator varchar(100),Keyword2 varchar(100))

insert into #tempKeyword (Keyword1,Operator,Keyword2)
select * 
from
(
select 'Tom' as Keyword1,  'AND' as Operator, 'Harry' as Keyword2
union all
select 'Krishna' as Keyword1,  'OR' as Operator, 'Radha' as Keyword2
union all
select 'Raju' as Keyword1,  'AND' as Operator, 'Radha' as Keyword2
) a

print 'Keyword Table'
select * from #tempKeyword


--Text table
select * into #tempText from
(
select 1 as Id, 'Tom and Harry Nice' as Text
union all
select 2 as Id, 'Tom Harry Raju Radha Nice' as Text
union all
select 3 as Id, 'Raju Radha Tom Nice' as Text
) b

print 'Text Table'
select * from #tempText

SET NOCOUNT ON

---- Script begin
declare @Keyword1  varchar(100)
declare @Operator  varchar(100)
declare @Keyword2  varchar(100)
declare @sql varchar(1000)

--settin loop counter variables
declare @start int
declare @end int
select @start=min(col_id),@end=max(col_id) from #tempKeyword 

--loop for #temp table
WHILE (@start <= @end)            
BEGIN

    select top 1 @Keyword1=Keyword1,@Operator=Operator,@Keyword2=Keyword2
    from #tempKeyword where col_id=@start

    --eliminate each rows with NOT condition from result table.
    select @sql='delete from #tempText where not ( Text like ''%' + @Keyword1 + 
    '%''' + @Operator +' Text like ''%' + @Keyword2 + '%'')'
    execute(@sql)
    
    --set Counter for Loop
    set @start = @start + 1
end

SET rowcount 0
--Result Output
print 'Results'
select * from #tempText
&#13;
&#13;
&#13;

我希望这会有所帮助:)

相关问题