标签: string-splitting

为charindex函数拆分/存储长字符串的最快方法

我有一个 1 TB 的数字串。给定一个 12 个字符的数字序列,我想获取该序列在原始字符串(charindex函数)中的起始位置。

我已经使用 SQL Server 使用 1GB 字符串和 9 位子字符串对此进行了测试,并将字符串存储为varchar(max). Charindex需要 10 秒。将 1GB 字符串分解为 900 字节重叠块并创建一个表(StartPositionOfChunk、Chunkofstring),其中包含二进制排序规则的 chunkofstring,索引时间不到 1 秒。10GB,10 位子字符串的后一种方法将 charindex 提高到 1.5 分钟。我想找到一种更快的存储方法。

例子

数字串:0123456789 - 要搜索的子字符串 345
charindex('345','0123456789') 给出 4

方法 1:我现在可以将其存储在包含一列的 SQL Server 表 strtable 中colstr并执行:

select charindex('345',colstr) from strtable
Run Code Online (Sandbox Code Playgroud)

方法2:或者我可以通过拆分原始字符串来组成一个表strtable2(pos,colstr1)1;012 | 2;123 | 3;234 aso然后我们可以进行查询

select pos from strtable2 where colstr1='345'
Run Code Online (Sandbox Code Playgroud)

方法 3:我可以通过将原始字符串拆分成更大的块来组成一个表strtable2 (pos2,colstr2) …

sql-server physical-design string-splitting sql-server-2017 string-searching

8
推荐指数
2
解决办法
839
查看次数

如何将 XML 数组拆分为单独的行(同时保持一致性)

我正在处理这个确切的堆栈交换部分的数据库转储。在我处理它的过程中,我遇到了一个我目前无法解决的问题。

在 XML 文件 Posts.xml 中,内容如下所示

在此处输入图片说明

当然有多行,但这就是一个的样子。转储中已经提供了一个 Tags.xml 文件,这使得该图片中的“Tags”属性实际上应该是它的单独表(多对多)变得更加明显。

所以现在我正试图找出一种如何提取标签的方法。这是我尝试做的:

CREATE TABLE #TestingIdea (
Id int PRIMARY KEY IDENTITY (1,1),
PostId int NULL,
Tag nvarchar (MAX) NULL
)
GO
Run Code Online (Sandbox Code Playgroud)

? 我创建的表来测试我的代码。我已经用标签和 PostIds 填充了它

SELECT  T1.PostId,
        S.SplitTag
FROM (
    SELECT  T.PostId, 
            cast('<X>'+ REPLACE(T.Tag,'>','</X><X>') + '</X>' as XML) AS NewTag
    FROM #TestingIdea AS T
    ) AS T1
CROSS APPLY (
    SELECT tData.value('.','nvarchar(30)') SplitTag
    FROM T1.NewTag.nodes('X') AS T(tData)
    ) AS S
GO
Run Code Online (Sandbox Code Playgroud)

然而此代码返回此错误

XML parsing: line 1, character 37, illegal qualified name character …
Run Code Online (Sandbox Code Playgroud)

xml sql-server xquery string-splitting sql-server-2017

6
推荐指数
1
解决办法
2431
查看次数

将逗号分隔的记录拆分为自己的行

我有下表,名为商店:

store_id INT
emails VARCHAR
Run Code Online (Sandbox Code Playgroud)

其中包含值:

商店ID 电子邮件
1 user_1@example.com,user2@example.com
2 uswe3@example.com,user4@example.com
4 admin@example.com

我想生成以下集合:

商店ID 电子邮件
1 user_1@example.com
1 user2@example.com
2 uswe3@example.com
2 user4@example.com
4 admin@example.com

正如您所看到的,我想将电子邮件字段拆分为仅包含一个电子邮件地址的单独记录。你知道我该怎么做吗?

到目前为止,我成功创建了以下查询:

select store_id,string_to_array(emails,',') from stores
Run Code Online (Sandbox Code Playgroud)

但我不知道如何将其拆分string_to_array为自己的行。

postgresql string-splitting

6
推荐指数
1
解决办法
1万
查看次数

将逗号分隔的字符串字段拆分/分解为 SQL 查询

我有场 id_list='1234,23,56,576,1231,567,122,87876,57553,1216'

我想用它来搜索IN这个领域:

SELECT * 
FROM table1
WHERE id IN (id_list)
Run Code Online (Sandbox Code Playgroud)
  • idinteger

  • id_listvarchar/text

但是这样就行不通了,所以我需要以某种方式拆分id_list为选择查询。

我应该在这里使用什么解决方案?我正在使用 T-SQL Sybase ASA 9 数据库 (SQL Anywhere)。但是这样就行不通了,所以我需要以某种方式拆分id_list为选择查询。

我看到的方式是使用while循环创建自己的函数,并根据分隔符位置搜索拆分每个元素提取,然后将元素插入到临时表中,该函数将作为结果返回。


对 Sebastian Meine 回答及其解决方案的评论:

Sybase SQL Anywhere 9

  • sa_split_list 系统程序在这里不存在,所以它不起作用

  • CAST 效果很好

Sybase SQL Anywhere 12

  • sa_split_list 系统程序存在并且运行良好

  • CAST 效果很好

对于 Sybase SQL Anywhere 9,我进行了 sa_split_list 系统过程替换:

CREATE PROCEDURE str_split_list(in str long varchar, in delim char(10) default ',')
RESULT(
  line_num integer,
  row_value long varchar)
BEGIN
  DECLARE str2 …
Run Code Online (Sandbox Code Playgroud)

sybase t-sql sybase-sql-anywhere string-splitting

5
推荐指数
1
解决办法
3万
查看次数

将 .csv 值匹配为 INT。如果 .csv 中某个组中的一个值与另一组中的一个值匹配,则合并字符串

这里我们有两组数字。问题是我无法弄清楚如何从数字的输入到输出(下面的 DDL 和 DML 以及这里的小提琴)。

current_data
1,2,3
1,4
1,5,7
8,9,10
10,11,15

expected_outcome
1,2,3,4,5,7
8,9,10,11,15
Run Code Online (Sandbox Code Playgroud)

我们只是尝试根据单个数字是否与任何其他组匹配来匹配一组数字。然后合并所有这些组。

例如。

如果我们有:

('1,2,3'),
('1,4'),
('1,5,7')
Run Code Online (Sandbox Code Playgroud)

我们想要:

(1,2,3,4,5,7)
Run Code Online (Sandbox Code Playgroud)

我们将它们合并为 PostgreSQL 中的一行。

或(另一个例子):

('8,9,10'), 
('10,11,15')
Run Code Online (Sandbox Code Playgroud)

所需的输出:

(8,9,10,11,15)
Run Code Online (Sandbox Code Playgroud)

查询将对这些数字进行分组,因为它们的共同点是数字 10。但它不会与(1,2,3,4,5,7)不共享数字的前一行(即)分组。

当我们将这些组放在一张表中时。如果他们在每一组中至少有一个匹配的号码,他们才会分组在一起。

======== DDL 和 DML ============

create table current (current_data text not null);
create table expected_output (expected_outcome text not null);

insert into current (current_data) values ('1,2,3'),('1,4'),('1,5,7'),('8,9,10'), ('10,11,15');
insert into expected_output (expected_outcome) values ('1,2,3,4,5,7'),('8,9,10,11,15');
Run Code Online (Sandbox Code Playgroud)

postgresql array string string-splitting string-searching

5
推荐指数
1
解决办法
94
查看次数

WHERE IN (1,2,3,4) 与 IN 之间的性能差距(select * from STRING_SPLIT('1,2,3,4',','))

我似乎在对 aSELECT IN和 a使用硬编码值之间存在巨大的性能差距STRING_SPLIT。除了最后一个阶段为STRING_SPLIT代码多次执行索引查找之外,查询计划是相同的。结果是大约 90000 与大约 15000(根据dm_exec_query_stats)的 CPU 时间,因此差异是巨大的。我已经在这里发布了两个计划......

  1. 硬编码计划
  2. 字符串拆分计划

有趣的是查询计划显示的成本几乎相同,但是当我检查dm_exec_query_stats成本 ( last_worker_time)时却大不相同。

这是查询计划的 2 个输出...

0x79DEAD79D1F149CD 16199 
select * 
from fn_get_samples(1) s 
where s.sample_id in 
    (2495,2496,2497,2498,2499,2500,2501,2502,2503,2504)

0x4A073840486B252C 86689 
select * 
from fn_get_samples(1) s 
where s.sample_id in 
    (select value as id 
     from 
     STRING_SPLIT('2495,2496,2497,2498,2499,2500,2501,2502,2503,2504',','))
Run Code Online (Sandbox Code Playgroud)

功能代码是...

CREATE FUNCTION [dbo].[fn_get_samples]
(
    @user_id int
)
RETURNS TABLE
AS
RETURN (
    -- get samples
    select s.sample_id,language_id,native_language_id,s.source_sentence,s.markup_sentence,s.latin_sentence,
        s.translation_source_sentence,s.translation_markup_sentence,s.translation_latin_sentence,
        isnull(sample_vkl.knowledge_level_id,1) as vocab_knowledge_level_id,
        isnull(sample_gkl.grammar_knowledge_level_id,0) as grammar_knowledge_level_id, …
Run Code Online (Sandbox Code Playgroud)

performance sql-server execution-plan string-splitting query-performance

3
推荐指数
1
解决办法
719
查看次数

如何将 Convert() 评估延迟到加入之后

以下查询转换表示 13k 行 x 2 列的打包 CSV 的单个字符串。A 列是一个 bigint。B 列是一个smallint。

declare
    @dataCsv nvarchar(max) = '29653,36,19603,36,19604,36,29654,36';  -- abbreviated, actually 13k rows

  with Input as
  (
      select Value,
             Row = row_number() over (order by (select null)) - 1
      from string_split(@dataCsv, ',') o
  )
  --insert into PubCache.TableName
  select 78064 as CacheId,
         convert(bigint, i.Value) as ObjectId,
         convert(smallint, i2.Value) as BrandId
    from Input i
    inner hash join Input i2    -- hash to encourage string_split() only once per column
      on i2.Row = i.Row + 1 …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan type-conversion string-splitting

3
推荐指数
1
解决办法
551
查看次数

SQL Server - 选择使用拆分的位置 - 不声明函数

SQL 服务器。兼容性级别 120。

我有一个表,其中一个 VARCHAR 列包含以分号分隔的整数值。我想对该列中的值进行 SELECT,就好像它们存在于某处的整数列中一样。

由于兼容级别,我不能使用 STRING_SPLIT。我也无法创建任何全局可用的函数。

但是,如果需要,我可以创建一个临时表。我的行动方针是什么?某种 WHILE 循环的嵌套(一个用于表的行,另一个用于字符串中的分号)?

更新:这可能是我想要实现的更好的解释:

假设我有以下表格。

CREATE TABLE Service
(
      ServiceId int
      , CustomerIds varchar(255)
);
Run Code Online (Sandbox Code Playgroud)
CREATE TABLE Customer
(
    CustomerId int
    , CustomerName varchar(30)
);
Run Code Online (Sandbox Code Playgroud)

有一些数据

INSERT INTO Customer (CustomerId, CustomerName)
VALUES  (1, 'John')
    ,(2, 'Niels')
    ,(3, 'Frank')
    ,(4, 'Barbie')
    ,(5, 'Holly')
    ,(6, 'Ebeneezer');
Run Code Online (Sandbox Code Playgroud)
INSERT INTO Service (ServiceId, CustomerIds)
VALUES  (1, '4')
    ,(2, '2;3');
Run Code Online (Sandbox Code Playgroud)

假设我想为任何客户选择 Customer.CustomerName,该客户的 ID 显示在该表中任何行的 CustomerIds 中。

也就是说,我想检索Niels,FrankBarbie

sql-server t-sql string-splitting

2
推荐指数
1
解决办法
975
查看次数

从双引号括起来的记录中删除一个字符

我有一个表,其中每一行都有如下数据:

0150566115,"HEALTH 401K","IC,ON","ICON HEALTH 401K",,,1,08/21/2014
Run Code Online (Sandbox Code Playgroud)

我想要的是删除,包含在双引号“”之间的每个逗号 ( )。然后用逗号 ( ,)分割字符串的其余部分

我不想检查双引号开始和结束的每个字符设置标志。

我可以实现某种正则表达式吗?

有没有简单的方法?

到目前为止,我所尝试的只是根据逗号 ( ,)拆分字符串,但它也在拆分引号内的值。

这是为了达到目的:如何在完整的表中实现这一点(目前,如果我只有一个双引号块实例,它就可以工作)?

Declare @Query nvarchar(max) 

Set @Query = 'Item1,Item2,"Item,Demo,3",New'

Declare @start int, @len int
SELECT @start = PATINDEX('%"%"%', @Query) + 1

print @start

select @len = CHARINDEX('"', SUBSTRING(@Query, @start, LEN(@Query))) - 1

select 
        SUBSTRING(@Query, 1, @start - 2) +
        REPLACE((SUBSTRING(@Query, @start, @len)), ',', '') +
        SUBSTRING(@Query, @start + @len + 1, LEN(@Query))
Run Code Online (Sandbox Code Playgroud)

这是我用来分割的函数

ALTER FUNCTION [dbo].[fnSplit](
    @sInputList VARCHAR(8000) -- List of …
Run Code Online (Sandbox Code Playgroud)

sql-server regular-expression t-sql string-splitting

0
推荐指数
1
解决办法
6468
查看次数