【问题标题】:Separating substrings from space separated values将子字符串与空格分隔的值分开
【发布时间】:2017-12-21 10:16:15
【问题描述】:

我在一列中有数据,我需要将其子串到一个新表中。我的问题是,有时第一列中的数据长度是 10 或 9 个字符,然后在第二列中是 9 或 8 个字符,所以我找不到统一的方法来对每个单独的部分进行子串化数据。

数据如下:

1465723732 353812955 2 88903391 N L 2016-06-28 13:48:57 2017-06-30 00:12:43 5
990459128 264834338 1 67093407 Y L 2001-01-01 00:00:00 2016-07-09 08:10:20 20
269660184 91753484 1 23492107 Y L 2000-01-01 00:00:00 2013-04-23 09:10:12 15

当第二列是 8 个字符时,第一列是 9 个字符。数据片段仅由一个空格分隔,而不是均匀地分成列,因此子字符串从下一个数据片段中获取数字,依此类推。

有人能建议一种方法吗?谢谢。

【问题讨论】:

  • 不是一个完整的答案,但我可以说这些数据甚至不应该在 MySQL 数据库中吗?您应该在将这些数据导入 MySQL 之前将其清理到单独的列中,并且有许多工具/语言非常适合此类文本操作。
  • 既然您被 MySQL 中的数据困住了,那么您所能做的事情就相当有限了。基本字符串函数不会有太大帮助,如果没有大量丑陋的代码。您可以尝试使用 UDF,但这对我来说似乎也没有吸引力。最好的办法是清除外部数据并将其带回。
  • 如果您的数据与您的示例完全相同,并且如果您使用的是最新版本的 SQL Server,那么您可以尝试使用带有空格分隔符的新 STRING_SPLIT 命令?

标签: sql sql-server substring charindex csv


【解决方案1】:

这并不优雅,但它会帮助你塑造数据:

WITH testdata(col) AS (
    SELECT '1465723732 353812955 2 88903391 N L 2016-06-28 13:48:57 2017-06-30 00:12:43 5' UNION
    SELECT '990459128 264834338 1 67093407 Y L 2001-01-01 00:00:00 2016-07-09 08:10:20 20' UNION
    SELECT '269660184 91753484 1 23492107 Y L 2000-01-01 00:00:00 2013-04-23 09:10:12 15'
), tempdata(cols) AS (
    SELECT CAST('<col>' + REPLACE(col, ' ', '</col><col>') + '</col>' AS XML)
    FROM testdata
)
SELECT
    cols.value('/col[1]', 'INT') AS col1,
    cols.value('/col[2]', 'INT') AS col2,
    cols.value('/col[3]', 'INT') AS col3,
    cols.value('/col[4]', 'INT') AS col4,
    cols.value('/col[5]', 'CHAR(1)') AS col5,
    cols.value('/col[6]', 'CHAR(1)') AS col6,
    cols.value('/col[7]', 'DATE') AS col7,
    cols.value('/col[8]', 'TIME(0)') AS col8,
    cols.value('/col[9]', 'DATE') AS col9,
    cols.value('/col[10]', 'TIME(0)') AS col10,
    cols.value('/col[11]', 'INT') AS col11
FROM tempdata

输出:

col1       | col2      | col3 | col4     | col5 | col6 | col7       | col8     | col9       | col10    | col11
-----------+-----------+------+----------+------+------+------------+----------+------------+----------+------
1465723732 | 353812955 | 2    | 88903391 | N    | L    | 2016-06-28 | 13:48:57 | 2017-06-30 | 00:12:43 | 5    
990459128  | 264834338 | 1    | 67093407 | Y    | L    | 2001-01-01 | 00:00:00 | 2016-07-09 | 08:10:20 | 20   
269660184  | 91753484  | 1    | 23492107 | Y    | L    | 2000-01-01 | 00:00:00 | 2013-04-23 | 09:10:12 | 15   

【讨论】:

  • 等等...所以只有一个空格?那就更容易了。请编辑您的 OP 并粘贴不带格式的准确数据。
  • @Tommy 你改变了数据库!无论如何,请参阅修改后的答案。
  • 您可能需要考虑使用CROSS APPLY,以便替换和转换为 XML 只出现一次,而不是重复出现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 2017-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多