需求
不同的商品使用逗号分隔保存,现在要求输入指定的商品名称,能够查询到包含该商品的列。
- 输入 K701 返回第1、2行
- 输入 K702 返回第2、4行
| 编号 |
商品 |
| 1 |
K701 |
| 2 |
K701,K702 |
| 3 |
K701B,K701C |
| 4 |
2K701,K702 |
解决思路
- 方法1:将商品列按照逗号分隔后列转行,然后在转换后的集合里查找符合条件的商品,最后用行ID去原始表反查
- 方法2: 将每一个商品名称格式化成
,*, 形式,然后使用like查询 like '%,*,%'
创建测试数据
创建数据表
1
2
3
4
|
CREATE TABLE TestQuery(
id INT,
k_value NVARCHAR(50)
)
|
添加数据
1
2
3
4
|
INSERT INTO dbo.TestQuery(id,k_value)VALUES(1,'K701')
INSERT INTO dbo.TestQuery(id,k_value)VALUES(2,'K701,K702')
INSERT INTO dbo.TestQuery(id,k_value)VALUES(3,'K701B,K701C')
INSERT INTO dbo.TestQuery(id,k_value)VALUES(4,'2K701,K702')
|
代码实现
方法1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
DECLARE @query_key NVARCHAR(10);
SET @query_key = 'K701';
SELECT *
FROM dbo.TestQuery
WHERE id IN (
SELECT C.id
FROM
(
SELECT A.id,
B.k_value
FROM
(
SELECT id,
CONVERT(XML, '<root><v>' + REPLACE(k_value, ',', '</v><v>') + '</v></root>') AS k_value
FROM TestQuery
) A
OUTER APPLY
(
SELECT id,
N.v.value('.', 'varchar(100)') AS k_value
FROM A.k_value.nodes('/root/v') N(v)
) B
) C
WHERE C.k_value = @query_key
);
|
方法2
这个方法中,我把分隔符逗号定义成了变量,因为直接拼接进sql中看起来不美观,如果为了简洁可以不使用变量
1
2
3
4
5
6
7
8
9
10
11
12
13
|
DECLARE @split_char NVARCHAR(10);
DECLARE @query_key NVARCHAR(10);
SET @split_char = ',';
SET @query_key = 'K702';
SELECT A.id,
SUBSTRING(A.k_value, 2, LEN(A.k_value) - 2) AS k_value
FROM
(
SELECT id,
@split_char + k_value + @split_char AS k_value
FROM dbo.TestQuery
) A
WHERE A.k_value LIKE '%' + @split_char + @query_key + @split_char + '%';
|