我有下一张桌子
Col1 Col2
1 ACA,ABS,PHR
2 PHR
3 MCM
4 ABC现在,我想从这里过滤数据,所以如果我有一个过滤器参数,比如'ABS,MCM',我只想得到至少有一个匹配代码的行。因此,在这种情况下,我应该得到过滤的结果,如
Col1 Col2
1 ACA,ABS,PHR
2 MCM现在我可以使用查询Select * from myTable where Col2 in ('ABS','MCM'),但是它不会检索第一行ACA,ABS,PHR。请告诉我如何进行文本代码搜索,只要在Col2中有一段代码匹配,我就可以得到行,这样我就可以直接传入分隔的列表,只要它找到单个匹配,行就会被检索。
谢谢
发布于 2019-02-14 19:31:41
还可以拆分字符串,然后搜索拆分后的值。一个例子可以是通过创建和使用这一功能。
从Server 2016开始,您可以使用内置的STRING_SPLIT()函数。
之后执行此查询
SELECT DISTINCT Col1,Col2
FROM dbo.Searching
CROSS APPLY dbo.fnSplitString(col2,',')
WHERE splitdata in ('ABS','MCM');Col1 Col2
1 ACA,ABS,PHR
3 MCM优化可以主动地将表拆分为永久的表,因此不需要每次都对整个表进行拆分。(如果值是静态的)
@Erikdarling的评论
有更好的方法来拆分字符串:字符串分割/级联方法的比较,包括杰夫·莫登(杰夫·莫登)中更好的一种。
实现
在他的博客中创建函数之后,您可以使用类似于前一个查询的查询。
SELECT Col1,Col2
FROM dbo.Searching
CROSS APPLY dbo.DelimitedSplit8k(Col2,',') split
WHERE split.Item in ('ABS','MCM');发布于 2019-02-14 20:04:37
当我看到filter参数时,我认为是存储过程的输入参数,所以在实际的查询中没有硬编码。这是@Randi版本的一个转折,它使用内联字符串拆分器技术将传入的参数拆分为行,并使用CROSS APPLY和LIKE查找匹配项。
--demo setup
declare @T table(col1 int, col2 varchar(100))
insert into @T(col1,col2) values
(1,'ACA,ABS,PHR'),
(2,'PHR'),
(3,'MCM'),
(4,'ABC')
--Declare the input parameter - passed into a stored procedure perhaps?
Declare @Parm varchar(100) = 'ABS,MCM'
--Common Table Expression - Inline string splitter, since you can't use STRING_SPLIT() from SQL 2016
;WITH SplitParms
AS (
SELECT LTRIM(RTRIM(m.n.value('.[1]', 'varchar(8000)'))) AS Code
FROM (
SELECT CAST('<XMLRoot><RowData>' + REPLACE(@Parm, ',', '</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x
) t
CROSS APPLY x.nodes('/XMLRoot/RowData') m(n)
)
--use CROSS APPLY and LIKE to find matching rows
SELECT t.*
FROM @t t
CROSS APPLY SplitParms sp
WHERE t.col2 LIKE ('%' + sp.Code + '%')| col1 | col2 |
|------|-------------|
| 1 | ACA,ABS,PHR |
| 3 | MCM |发布于 2019-02-15 00:54:06
最正确的解决办法是正常化。您需要使用外键将代码放在另一个表中:
CREATE TABLE MyThings (
Col1 IDENTITY PRIMARY KEY,
-- Other columns you already have on the table
Col3 VARCHAR(200) NOT NULL,
Col4 DECIMAL NOT NULL
);
-- Probably needs some kind of primary key.
CREATE TABLE MyThingCodes (
Col1 NOT NULL REFERENCES MyThings (Col1),
Code VARCHAR(30) NOT NULL
);我们可以索引它(因为代码很短)来加速这些查询:
CREATE INDEX idx_MyThingCodes_Code ON MyThingCodes (Code);然后可以使用EXISTS查询查找与代码匹配的行:
SELECT *
FROM MyThings
WHERE EXISTS (
SELECT 1
FROM MyThingCodes
WHERE
MyThingCodes.Col1 = MyThings.Col1
AND MyThingCodes.Code IN ('ABS','MCM')
)https://dba.stackexchange.com/questions/229784
复制相似问题