首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用进行筛选

使用进行筛选
EN

Database Administration用户
提问于 2019-02-14 19:05:32
回答 5查看 492关注 0票数 0

我有下一张桌子

代码语言:javascript
复制
Col1       Col2
1          ACA,ABS,PHR
2          PHR
3          MCM
4          ABC

现在,我想从这里过滤数据,所以如果我有一个过滤器参数,比如'ABS,MCM',我只想得到至少有一个匹配代码的行。因此,在这种情况下,我应该得到过滤的结果,如

代码语言:javascript
复制
Col1       Col2
1          ACA,ABS,PHR
2          MCM

现在我可以使用查询Select * from myTable where Col2 in ('ABS','MCM'),但是它不会检索第一行ACA,ABS,PHR。请告诉我如何进行文本代码搜索,只要在Col2中有一段代码匹配,我就可以得到行,这样我就可以直接传入分隔的列表,只要它找到单个匹配,行就会被检索。

谢谢

EN

回答 5

Database Administration用户

回答已采纳

发布于 2019-02-14 19:31:41

还可以拆分字符串,然后搜索拆分后的值。一个例子可以是通过创建和使用这一功能

从Server 2016开始,您可以使用内置的STRING_SPLIT()函数。

从blogpost创建函数,并在

之后执行此查询

代码语言:javascript
复制
SELECT DISTINCT Col1,Col2 
FROM dbo.Searching
CROSS APPLY dbo.fnSplitString(col2,',')
WHERE splitdata in ('ABS','MCM');

结果

代码语言:javascript
复制
Col1    Col2
1   ACA,ABS,PHR
3   MCM

DB<>Fiddle

优化可以主动地将表拆分为永久的表,因此不需要每次都对整个表进行拆分。(如果值是静态的)

编辑

@Erikdarling的评论

有更好的方法来拆分字符串:字符串分割/级联方法的比较,包括杰夫·莫登(杰夫·莫登)中更好的一种。

函数由杰夫·莫登

实现

在他的博客中创建函数之后,您可以使用类似于前一个查询的查询。

代码语言:javascript
复制
  SELECT Col1,Col2
  FROM dbo.Searching
  CROSS APPLY dbo.DelimitedSplit8k(Col2,',') split
  WHERE split.Item in ('ABS','MCM');

DB<>Fiddle

票数 4
EN

Database Administration用户

发布于 2019-02-14 20:04:37

当我看到filter参数时,我认为是存储过程的输入参数,所以在实际的查询中没有硬编码。这是@Randi版本的一个转折,它使用内联字符串拆分器技术将传入的参数拆分为行,并使用CROSS APPLYLIKE查找匹配项。

代码语言:javascript
复制
--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 + '%')
代码语言:javascript
复制
| col1 | col2        |
|------|-------------|
| 1    | ACA,ABS,PHR |
| 3    | MCM         |
票数 4
EN

Database Administration用户

发布于 2019-02-15 00:54:06

最正确的解决办法是正常化。您需要使用外键将代码放在另一个表中:

代码语言:javascript
复制
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
);

我们可以索引它(因为代码很短)来加速这些查询:

代码语言:javascript
复制
CREATE INDEX idx_MyThingCodes_Code ON MyThingCodes (Code);

然后可以使用EXISTS查询查找与代码匹配的行:

代码语言:javascript
复制
SELECT *
FROM MyThings
WHERE EXISTS (
    SELECT 1
    FROM MyThingCodes
    WHERE
        MyThingCodes.Col1 = MyThings.Col1
        AND MyThingCodes.Code IN ('ABS','MCM')
)
票数 2
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/229784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档