如果数据库表格单元格的内容是一个列表,我如何检查该列表是不是包含 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 个或更多不同的视图

谷歌表格,如何根据来自另一个单元格的字符串更改单元格

如何识别线性布局中一系列表格单元格的视图ID

如何找到表格列,然后向下移动并替换单元格的内容,如果它是“N/A”

如何动态更改自定义单元格的表格视图单元格的高度?