在文本列中的模式匹配

时间:2011-08-02 23:32:47

标签: sql-server sql-server-2005 tsql sql-server-2008 pattern-matching

我有一个文本列,文本列中的数据如下:

Rob goes to school,get punished
Rob goes to school
Rob does not goes to school,get punished

尝试使用像

这样的case语句编写查询时
CASE 
    WHEN (PATINDEX('%Rob goes to school%',value) > 0) OR
         (PATINDEX('%Rob is ill%',value) > 0 ) AND
         (PATINDEX(%get punished%',value) > 0) THEN
           'DONE'

它应该只选择第一个语句,而是选择带有'DONE'的第一个和第二个语句。在这种情况下,有什么建议如何进行模式匹配? 我正在使用SQL Sever 2005/2008

2 个答案:

答案 0 :(得分:1)

Operator precedenc e并且可能没有足够的括号

x OR y AND z实际上是x OR (y AND z)。你想要(x OR y) AND z吗?

  • 第二条陈述给出true OR (false AND false),其中true
  • 您希望(true OR false) AND false提供false

所以SQL应该是

CASE WHEN
   (
      PATINDEX('%Rob goes to school%', value) > 0
      OR
      PATINDEX('%Rob is ill%', value) > 0
   )
   AND
   (PATINDEX(%get punished%', value) > 0) THEN 'DONE'
...

答案 1 :(得分:0)

PATINDEX不会将您的字符串视为分隔列表(以逗号分隔的值) - 它会搜索与整个字符串匹配的内容。

Rob上学,受到惩罚 罗布上学

PATINDEX('%Rob上学%',价值)>因为wildcard % matches any string of 0 or more characters,0对它们的计算结果为真。你的第二和第三种模式永远不会被评估。

If you want to test which pattern is returning true, try this:
CASE 
    WHEN (PATINDEX('%Rob goes to school%',value) > 0) THEN 'Pattern 1'
    WHEN (PATINDEX('%Rob is ill%',value) > 0 ) THEN 'Pattern 2'
    WHEN (PATINDEX('%get punished%',value) > 0) THEN 'Pattern 3'
    ELSE 'No Match Found' END

如果您希望模式匹配第一个值而不是第二个值,请使用逗号查找(PATINDEX('%Rob goes to school,%',value) > 0)

否则 - 如果您想要像逗号分隔值一样处理字符串,PATINDEX不是您的最佳工具。其他选项可能包括通过表值函数将字符串转换为表格,或者包含哪些内容。