如果数据库表格单元格的内容是一个列表,我如何检查该列表是不是包含 T-SQL 中的特定值?
Posted
技术标签:
【中文标题】如果数据库表格单元格的内容是一个列表,我如何检查该列表是不是包含 T-SQL 中的特定值?【英文标题】:If the contents of a database table cell is a list, how do I check if the list contains a specific value in T-SQL?如果数据库表格单元格的内容是一个列表,我如何检查该列表是否包含 T-SQL 中的特定值? 【发布时间】:2012-03-05 20:51:58 【问题描述】:我有一个 SQL Server 数据库表,其中有一列称为资源。此列的每个单元格都包含一个以逗号分隔的整数列表。所以表格数据可能如下所示:
Product_ID Resources Condition
1 12,4,253 New
2 4,98,102,99 New
3 245,88 Used
etc....
我想返回资源列中包含资源 ID 号的行。这不起作用,但是像这样:
SELECT *
FROM product_table
WHERE resources CONTAINS 4
如果这有效,它将返回 product_id 1 和 2 的行,因为这些行中的两个资源单元格都包含值 4。它不会返回 product_id 3,即使该行的资源单元格具有编号4,因为它不是完整的逗号分隔值。
这样做的正确方法是什么?
【问题讨论】:
它应该只返回产品 id 2。 正确的做法是规范化数据,但也许你没有那个选项。 【参考方案1】:使用this 资源中概述的拆分功能:
CREATE FUNCTION Split
(
@delimited nvarchar(max),
@delimiter nvarchar(100)
) RETURNS @t TABLE
(
-- Id column can be commented out, not required for sql splitting string
id int identity(1,1), -- I use this column for numbering splitted parts
val nvarchar(max)
)
AS
BEGIN
declare @xml xml
set @xml = N'<root><r>' + replace(@delimited,@delimiter,'</r><r>') + '</r></root>'
insert into @t(val)
select
r.value('.','varchar(5)') as item
from @xml.nodes('//root/r') as records(r)
RETURN
END
GO
-- Create the test table and insert the test data
create table #test
(
product_id int,
resources nvarchar(max),
condition nvarchar(10)
);
insert into #test (product_id, resources, condition)
select 1, '12,4,253', 'new'
union
select 2, '4,98,102,99', 'new'
union
select 3, '245,88', 'used';
-- Use the Split function and cross apply to grab the data you need
select product_id, val, condition
from #test
cross apply dbo.split(#test.resources,',') split
where val = '4' -- split returns a string so use single quotes
【讨论】:
【参考方案2】:你可以这样做......
select *
from product_table
where ',' + resources + ',' like '%,4,%'
但这可能不会使用索引,因此如果表很大,它会很慢。 如果可能的话,一个更好的解决方案是通过使用带有 product_id 和 resource_id 的额外表来规范化,其值如 (1,12)、(1,4)、(1, 253)、(2,4) 等。这会很多更快,因为它会使用索引
【讨论】:
这就是为什么在资源之前和之后都有一个','【参考方案3】:首先,如果您对架构有任何控制权,那么真正正确的方法是拥有一个多对多资源表,这样您就不需要逗号分隔的列表.
除此之外,您需要一组与 OR 连接的 LIKE 案例,以处理您想要的项目是第一个项目、最后一个项目、中间项目之一或唯一的不同情况项目。
【讨论】:
【参考方案4】:或者使用here描述的拆分功能 并这样称呼它:
select * from Products where exists (select * from dbo.Split(',', Resources) where s = '4')
【讨论】:
以上是关于如果数据库表格单元格的内容是一个列表,我如何检查该列表是不是包含 T-SQL 中的特定值?的主要内容,如果未能解决你的问题,请参考以下文章
如何将EXCEL表格中的同一列有相同的内容 合并成一个单元格?
如何从一个带有动态单元格的表格切换到 3 个或更多不同的视图