【问题标题】:Get the values from a column with string delimeter从带有字符串分隔符的列中获取值
【发布时间】:2013-05-29 13:13:07
【问题描述】:

我只想知道如何使用 select 从带有字符串分隔符的列中获取值。

例如: 列值为:

    ';#10;~Banana;#101;~Apple'

如何获取这些值并保存在这样的表格中?

    code   description
    10     Banana
    101    Apple

似乎无法使用 substring、charindex 组合来获取它。我应该改用函数吗? 基本上,此列有可能存储 100 多个值(代码/说明)。

【问题讨论】:

  • 数据是这样存储的吗?还是从文本文件导入?
  • 这是 SQL Server 还是 Sybase?
  • 是的,数据作为 SQL Server 表中的给定样本值存储在列中

标签: sql-server tsql


【解决方案1】:

你可以试试上面的(用';'代替','):

CREATE FUNCTION dbo.fnSplit(
    @sInputList VARCHAR(8000) -- List of delimited items
  , @sDelimiter VARCHAR(8000) = ',' -- delimiter that separates items
) RETURNS @List TABLE (item VARCHAR(8000))

BEGIN
DECLARE @sItem VARCHAR(8000)
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
 BEGIN
 SELECT
  @sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1))),
  @sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))

 IF LEN(@sItem) > 0
  INSERT INTO @List SELECT @sItem
 END

IF LEN(@sInputList) > 0
 INSERT INTO @List SELECT @sInputList -- Put the last item in
RETURN
END
GO



select * from dbo.fnSplit('1,22,333,444,,5555,666', ',')

Results

Item

1
22
333
444
5555
666

【讨论】:

  • 仅链接的答案不是好的答案。如果链接死了,答案就变得毫无用处。请在实际答案中总结页面的基本部分。
【解决方案2】:

尝试使用 XML 节点方法 (SQL-FIDDEL)

DECLARE @S VARCHAR(500)= ';#10;~Banana;#101;~Apple'

--REMOVE LEADING ROW DELIMETER `;#`
SELECT @S = SUBSTRING(@S,3, LEN(@S))


DECLARE @X XML 
SELECT @X  = '<myxml><nodes><n1>' + 
REPLACE(REPLACE (@S,';#','</n2></nodes><nodes><n1>'),';~','</n1><n2>') + 
'</n2></nodes></myxml>'


SELECT C.value('n1[1]','VARCHAR(50)') AS code,
       C.value('n2[1]','VARCHAR(50)') AS description
FROM @X.nodes('/myxml/nodes') Cols (C)


| CODE | DESCRIPTION |
----------------------
|   10 |      Banana |
|  101 |       Apple |

【讨论】:

  • 好一个...这正是我所需要的。非常感谢卡夫! :)
  • 嗨,Kaf,不确定是否可以发布另一个问题...但在某些情况下,我只需要在以逗号“,”分隔的一行中返回描述。这可能吗? TIA :)
  • 我认为您可以使用 UDF 来做到这一点。将您的字符串列传递给函数并返回过滤后的 csv 描述列表。您可以使用内置的字符串函数,例如CharindexSubstringleft/right 来实现。
【解决方案3】:

或者简单的子字符串';'

select 
   substr( column, INSTR(column, ';', 1, 1)+1, 
   (INSTR(column, ';', 1, 2 ) - INSTR(column, 1, 1 ))
   ) col_a,
   substr( column, INSTR(column, ';', 1, 2)+1, 
   (INSTR(column, ';', 1, 3 ) - INSTR(column, ';', 1, 2 ))
   ) col_b
from dual

工作示例:

select 
   substr( ';#10;~Banana;#101;~Apple', INSTR(';#10;~Banana;#101;~Apple', ';', 1, 1)+1, 
    (INSTR(';#10;~Banana;#101;~Apple', ';', 1, 2 ) - INSTR(';#10;~Banana;#101;~Apple', ';', 1, 1 ))
   ) col_a,
   substr( ';#10;~Banana;#101;~Apple', INSTR(';#10;~Banana;#101;~Apple', ';', 1, 2)+1, 
   (INSTR(';#10;~Banana;#101;~Apple', ';', 1, 3 ) - INSTR(';#10;~Banana;#101;~Apple', ';', 1, 2 ))
   ) col_b
from dual

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多