使用模式匹配将值从单个列返回为多行?

时间:2017-04-24 19:37:13

标签: sql-server sql-server-2008

我有这个查询 SELECT TOP 1 text FROM [pageContent] WHERE pageid = 5

返回具有以下值的字段

<table style="width: 100%;border:none !important">
        <tr style="border:none !important">
            <td style="border:none !important">

**[[http://mypage.com/123/data1|data1]]**

**[[http://mypage.com/345/data2|data2]]**

**[[http://mypage.com/567/data3|data3]]**

          </td>
      </tr>
</table>

我想要的是返回以'**[['开头并以']]**'结尾的数据 返回3行。像下面的东西,

enter image description here

  1. 我到目前为止尝试的是用空字符串替换整个html标签,并使用从互联网获取的分割功能。
  2. 使用函数删除html内容并使用拆分功能拆分内容。
  3. 我想知道的是,有没有办法对字段进行模式匹配,这样如果一行包含一个字符串,以'**[['开头,以']]**'结尾,并返回多行。< / p>

    非常感谢任何建议。

1 个答案:

答案 0 :(得分:0)

字符串拆分器是可行的方法,但如果你做得对,你根本不需要关心html:

首先,创建分割字符串函数。我使用了一个基于Jeff Moden的分裂字符串的函数,该字符取自Aaron Bertrand的Split strings the right way – or the next best way文章:

CREATE FUNCTION dbo.SplitStrings
(
   @List NVARCHAR(MAX),
   @Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING AS
RETURN
  WITH E1(N)        AS ( SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
                         UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
                         UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1),
       E2(N)        AS (SELECT 1 FROM E1 a, E1 b),
       E4(N)        AS (SELECT 1 FROM E2 a, E2 b),
       E42(N)       AS (SELECT 1 FROM E4 a, E2 b),
       cteTally(N)  AS (SELECT 0 UNION ALL SELECT TOP (DATALENGTH(ISNULL(@List,1))) 
                         ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E42),
       cteStart(N1) AS (SELECT t.N+1 FROM cteTally t
                         WHERE (SUBSTRING(@List,t.N,1) = @Delimiter OR t.N = 0))
  SELECT Item = SUBSTRING(@List, s.N1, ISNULL(NULLIF(CHARINDEX(@Delimiter,@List,s.N1),0)-s.N1,8000))
    FROM cteStart s;

GO

然后,创建并填充样本表(在将来的问题中将此步骤保存起来)

CREATE TABLE pageContent
(
    [text] varchar(1000),
    pageid int
)

INSERT INTO pageContent VALUES
('<table style="width: 100%;border:none !important">
        <tr style="border:none !important">
            <td style="border:none !important">

**[[http://mypage.com/123/data1|data1]]**

**[[http://mypage.com/345/data2|data2]]**

**[[http://mypage.com/567/data3|data3]]**

          </td>
      </tr>
</table>', 5)

现在,对于查询,我使用CROSS APPLY和基于您在问题中发布的查询的派生表:

SELECT  LTRIM(RTRIM(Item)) As Content
FROM 
(
    SELECT TOP 1 text FROM [pageContent] WHERE pageid = 5
) query
CROSS APPLY
dbo.SplitStrings(text, char(10))
WHERE Item LIKE '%**%**%'

结果:

Content
**[[http://mypage.com/123/data1|data1]]**
**[[http://mypage.com/345/data2|data2]]**
**[[http://mypage.com/567/data3|data3]]**

You can see a live demo on rextester.