选择列中具有特定数量的特定字符类型的行

时间:2014-05-12 15:17:10

标签: sql sql-server

Microsoft SQL Server

我需要一个查询,它将返回描述列中存在大于X个逗号的所有行。喜欢不会起作用,因为逗号会展开,文本之间会有所不同。我不确定这个查询是否存在。

对此有任何见解或帮助将不胜感激。

感谢您的时间。

2 个答案:

答案 0 :(得分:4)

计算字符在字符串中出现的次数的一种方法是将字符串的长度与删除此字符的字符串长度进行比较。

因此,例如,假设您要在col1中找到包含5个逗号的所有行:

SELECT *
FROM   my_table
WHERE  LEN(col1) - LEN(REPLACE(col1, ',', '')) = 5

答案 1 :(得分:1)

如果您对性能感兴趣,并希望实现稍微复杂一些的方法,我会模拟一些数据并进行相对简单的测试:

CREATE TABLE dbo.Test
(
    TestID INT NOT NULL CONSTRAINT PK_Test
        PRIMARY KEY CLUSTERED IDENTITY(1,1)
    , col1 VARCHAR(255) NOT NULL
    , col1_comma_count AS LEN(col1) - LEN(REPLACE(col1, ',','')) PERSISTED
);


INSERT INTO Test (col1) VALUES ('this, is, a, test');
GO 50000
INSERT INTO Test (col1) VALUES ('this, is, a, test, another, test');
GO 1500

上述语句创建一个测试表,其中包含一个计算列,其中包含col1中逗号数的计数。然后该表插入50,000行,逗号计数为3,插入1,500行,逗号计数为5。

然后,我使用SET STATISTICS IO ON; SET STATISTICS TIME ON;执行了以下查询:

SELECT COUNT(1)
FROM dbo.Test t
WHERE t.col1_comma_count = 5;

统计信息:

enter image description here

如您所见,扫描整个表以获取5个逗号的行数需要248次逻辑读取。此查询的执行计划如下所示:

enter image description here

正如所料,SQL Server对整个表执行聚簇索引扫描。

然后我在持久计算列上创建了一个索引,以显示差异:

CREATE INDEX IX_Test_col1_comma_count ON dbo.Test (col1_comma_count);

并重新运行测试查询。以下是使用索引运行的统计信息:

enter image description here

必要的读取次数已降至6次,或读取次数减少41次。在繁忙的系统上,这将产生真正的不同。这是新的执行计划:

enter image description here

这一次,我们看到了对指数的更有效追求。

如果我们从表中删除索引和计算列,我们会看到获取查询结果所花费的时间大大增加:

DROP INDEX IX_Test_col1_comma_count ON dbo.Test;
ALTER TABLE Test DROP COLUMN col1_comma_count;

SELECT COUNT(1)
FROM dbo.Test t
WHERE LEN(col1) - LEN(REPLACE(col1, ',','')) = 5

STATISTICS TIME ON显示我的计算机(Intel Core-i7 3.4Ghz,8GB内存)的SQL Server执行时间值:CPU时间= 15毫秒,已用时间= 24毫秒。

使用索引和计算的持久列,SQL Server执行时间是SQL Server执行时间:CPU时间= 0毫秒,已用时间= 2毫秒。

显然,在WHERE子句中进行字符串操作需要付出代价。