解析数据,单个到多个

时间:2014-07-22 17:48:52

标签: sql sql-server

只有一列Varchar(2000)

数据看起来像一列,

12:10:08: Dialing12:10:08: Connecting12:10:08: ABC: abc:9433769781$100.88.77.0:878712:10:08: ABCD: 000012:10:09: Agent Initializing12:10:25: On Call12:10:25: Assigned to operator12:10:25: Waiting for Supervisor12:10:30: Waiting for Manager12:11:30: Call Ended12:11:30: Call Not connected.. 

我想解析它,

12:10:08: Dialing
12:10:08: Connecting
12:10:08: ABC: abc:9433769782$100.88.77.0:8787
12:10:08: ABCD: 0000
12:10:25: Agent Initializing
12:10:18: On Call
12:10:25: Assigned to operator
12:10:30: Waiting for Supervisor
12:10:30: Waiting for Manager
12:11:30: Call Ended
12:11:30: Call Not connected

任何帮助。搜索完整的论坛,但我真的不确定这一点,特别是没有特定的标识符。感谢您的帮助。

P / S-这只是一个时间的例子,时间不是恒定的。

3 个答案:

答案 0 :(得分:1)

呸。但是,您可以使用递归CTE执行此操作。方法如下:

with t as (
      select '12:10:08: Dialing12:10:08: Connecting12:10:08: ABC: abc:9433769781$100.88.77.0:878712:10:08: ABCD: 000012:10:09: Agent Initializing12:10:25: On Call12:10:25: Assigned to operator12:10:25: Waiting for Supervisor12:10:30: Waiting for Manager12:11:30: Call Ended12:11:30: Call Not connected.. ' as col
     ),
     cte as (
      select left(t.col, 9 + patindex('%[0-9][0-9]:[0-9][0-9]:[0-9][0-9]: %', substring(t.col, 11, 1000))) as val,
             substring(t.col, 10 + patindex('%[0-9][0-9]:[0-9][0-9]:[0-9][0-9]: %', substring(t.col, 11, 1000)), 1000) as rest
      from t
      where t.col like '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]: %[0-9][0-9]:[0-9][0-9]:[0-9][0-9]: %'
      union all
      select (case when rest like '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]: %[0-9][0-9]:[0-9][0-9]:[0-9][0-9]: %'
                   then left(rest, 9 + patindex('%[0-9][0-9]:[0-9][0-9]:[0-9][0-9]: %', substring(rest, 11, 1000)))
                   else rest
              end) as val,
             substring(rest, 10 + patindex('%[0-9][0-9]:[0-9][0-9]:[0-9][0-9]: %', substring(rest, 11, 1000)), 1000) as rest
      from cte
      where rest like '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]: %'
     )
select val
from cte;

SQL小提琴是here

答案 1 :(得分:1)

替代;

DECLARE @string VARCHAR(1024) = '12:10:08: Dialing12:10:08: Connecting12:10:08: ABC: abc:9433769781$100.88.77.0:878712:10:08: ABCD: 000012:10:09: Agent Initializing12:10:25: On Call12:10:25: Assigned to operator12:10:25: Waiting for Supervisor12:10:30: Waiting for Manager12:11:30: Call Ended12:11:30: Call Not connected'

WITH T(last, pos) AS(
        SELECT 0, 1
        UNION ALL
        SELECT pos, pos + PATINDEX('%[0-9][0-9]:[0-9][0-9]:[0-9][0-9]%', SUBSTRING(@string, pos + 1, LEN(@string)))
        FROM T
        WHERE pos != last
    )
    SELECT SUBSTRING(@string, last, CASE WHEN pos = last THEN len(@string) ELSE pos - last END)
    FROM T
    WHERE LAST > 0

有关

(No column name)
12:10:08: Dialing
12:10:08: Connecting
12:10:08: ABC: abc:9433769781$100.88.77.0:8787
12:10:08: ABCD: 0000
12:10:09: Agent Initializing
12:10:25: On Call
12:10:25: Assigned to operator
12:10:25: Waiting for Supervisor
12:10:30: Waiting for Manager
12:11:30: Call Ended
12:11:30: Call Not connected

答案 2 :(得分:0)

我知道你要求一个SQL解决方案,但我不确定如果没有while循环和广泛的字符串操作,这是非常低效的。

如果您乐意将原始varchar降低到BLL级别,可以使用正则表达式在此处执行此操作。正如我假设您要这样做以输出到屏幕或日志文件,那么这应该是可能的。

例如: 取代

/([0-9]{2}:[0-9]{2}:[0-9]{2}: ).*/gU

\n/1

实施例: http://regex101.com/r/eM4vD5/1