如何在大描述值中查找字符串

时间:2016-05-14 14:48:25

标签: sql sql-server

我有2列ID和说明。我想获得每个ID列的唯一mailid。

stdClass Object ( [balance] => 998 
[batch_id] => 243941208 
[cost] => 1 
[num_messages] => 1 
[message] => stdClass Object ( [num_parts] => 1 [sender] => TMTLCO [content] => @U0D070D240D4D00200D120D300D4100200D1F0D460D380D4D0D310D4D0D310D4D002000200D060D230D4D ) [receipt_url] => [custom] => [messages] => Array ( [0] => stdClass Object ( [id] => 117250619 [recipient] => XXXXXXXX ) ) [status] => success ) 

预期输出

ID  Description
1   I have 2 mailID please note this mai1: anto1@gmail.com and mai1: anto2@gmail.com and mai1: anto3@gmail.com abbaaabbbbbbb.
2   I have 2 mailID please note this mai1: sample1@gmail.com and mai1: sample2@gmail.com and mai1: sample3@gmail.com abbaaabbbbbbb.

我已尝试过以下查询。

ID  Description
1   anto1@gmail.com
1   anto2@gmail.com
1   anto3@gmail.com
2   sample1@gmail.com
2   sample2@gmail.com
2   sample3@gmail.com

但请提供备用有效查询。

4 个答案:

答案 0 :(得分:2)

也许是这样的......

测试数据

Declare @table TABLE(ID int , Description Varchar(8000))
INsert into @table values
(1 ,  'I have 2 mailID please note this mai1: anto1@gmail.com and mai1: anto2@gmail.com and mai1: anto3@gmail.com abbaaabbbbbbb'),
(2 ,  'I have 2 mailID please note this mai1: sample1@gmail.com and mai1: sample2@gmail.com and mai1: sample3@gmail.com abbaaabbbbbbb')

查询

Select ID
     ,LEFT(RTRIM(LTRIM(Emails)) , CHARINDEX(' ' , RTRIM(LTRIM(Emails)))) Emails
from 
(
SELECT t.ID 
          ,Split.a.value('.', 'VARCHAR(100)') Emails
FROM   
    (SELECT Cast ('<X>' + Replace(Description, ':', '</X><X>') + '</X>' AS XML) AS Data
            ,ID
    FROM    @table
    ) AS t CROSS APPLY Data.nodes ('/X') AS Split(a)
 )a 
Where a.emails LIKE '%@%'

结果集

╔════╦════════════════════╗
║ ID ║       Emails       ║
╠════╬════════════════════╣
║  1 ║ anto1@gmail.com    ║
║  1 ║ anto2@gmail.com    ║
║  1 ║ anto3@gmail.com    ║
║  2 ║ sample1@gmail.com  ║
║  2 ║ sample2@gmail.com  ║
║  2 ║ sample3@gmail.com  ║
╚════╩════════════════════╝

答案 1 :(得分:1)

DECLARE @xml xml
--- Remove from here...    
;WITH cte AS (
SELECT *
FROM (VALUES
(1, 'I have 2 mailID please note this mai1: anto1@gmail.com and mai1: anto2@gmail.com and mai1: anto3@gmail.com abbaaabbbbbbb.'),
(2, 'I have 2 mailID please note this mai1: sample1@gmail.com and mai1: sample2@gmail.com and mai1: sample3@gmail.com abbaaabbbbbbb.')
) as t(ID, [Description])
)
-- To here
SELECT @xml = (
    SELECT CAST('<i id="' + CAST(id as nvarchar(10)) + '"><a>' +REPLACE([Description],' ','</a><a>') +'</a></i>' as xml)
    FROM cte -- here change cte to your table name
    FOR XML PATH ('')
)

SELECT  t.v.value('../@id', 'int') as id,
        t.v.value('.', 'nvarchar(100)') as email
FROM @xml.nodes('/i/a') as t(v)
WHERE t.v.value('.', 'nvarchar(100)') like '%@%'

输出:

id  email
1   anto1@gmail.com
1   anto2@gmail.com
1   anto3@gmail.com
2   sample1@gmail.com
2   sample2@gmail.com
2   sample3@gmail.com

答案 2 :(得分:0)

SELECT SUBSTRING(Description, CHARINDEX('mai1:', Description) + 5, CHARINDEX('mai1:', Description))
FROM Table
WHERE Description LIKE '%mai1:%'
  AND CHARINDEX('mai1:', Description) > 0

答案 3 :(得分:0)

由于我对SQL服务器的了解有限(可能在oracle中使用REGEXP_SUBSTR执行此操作),因此不是一个强大的解决方案。它限制为3个或更少的电子邮件,如果需要更多,则必须手动扩展。发布的其他解决方案之一可能更好,但只是想把它放在这里:

with temp(ID,  Description)
as(
select 1, 'I have 2 mailID please note this mai1: anto1@gmail.com and mai1: anto2@gmail.com and mai1: anto3@gmail.com abbaaabbbbbbb.' union all
select 2, 'I have 2 mailID please note this mai1: sample1@gmail.com and mai1: sample2@gmail.com and mai1: sample3@gmail.com abbaaabbbbbbb.'
)

SELECT
 ID,
 EMAIL
from (
  select
  ID,
  case when start1 > 0 then substring(Description, start1+2, end1-start1+2) end email1,
  case when start2 > 0 then substring(Description, start2+2, end2-start2+2) end email2,
  case when start3 > 0 then substring(Description, start3+2, end3-start3+2) end email3
  from (
    select ID, Description,
      start1 = ISNULL(CHARINDEX(':', Description, 0),0),
      start2 = ISNULL(CHARINDEX(':', Description, CHARINDEX(':', Description, 0)+1),0),
      start3 = ISNULL(CHARINDEX(':', Description, CHARINDEX(':', Description, CHARINDEX(':', Description, 0)+1)+1),0),
      end1 = ISNULL(CHARINDEX('.com', Description, 0),0),
      end2 = ISNULL(CHARINDEX('.com', Description, CHARINDEX('.com', Description, 0)+4),0),
      end3 = ISNULL(CHARINDEX('.com', Description, CHARINDEX('.com', Description, CHARINDEX('.com', Description, 0)+4)+4),0)
    from temp  ) as pos
    ) temp1
CROSS APPLY
(
  VALUES
  (email1),
  (email2),
  (email3)
) temp2 (email)
where EMAIL is NOT NULL