每个“产品”最多可以有 10000 个“分割”行。这些段有一个排序列,每个产品(1、2、3、4、5,...)从 1 开始,还有一个值列,可以包含任何值,例如(323.113、5423.231、873.42、422.64、763.1、 ...)。
我想在给定分割子集的情况下确定产品的潜在匹配项。例如,如果我有 5 个顺序正确的段值,我如何才能在段表中的某处有效地找到所有 5 个段的顺序相同的所有产品?
更新
我在这里发布了一个后续问题:Find a series of data using non-exact measurements (fuzzy logic)
最佳答案
假设表是这样的:
CREATE TABLE Products
(
ProductId int not null
constraint PK_Products
primary key
,Name varchar(100) not null
)
CREATE TABLE Segments
(
ProductId int not null
constraint FK_Segments__Products
foreign key references Products (ProductId)
,OrderBy int not null
,Value float not null
,constraint PK_Segments
primary key (ProductId, OrderBy)
)
接下来,在临时表中设置搜索数据:
CREATE TABLE #MatchThis
(
Position int not null
,Value float not null
)
对于 N 个搜索对象,必须像这样填充
First item 0 <value 1>
Second item 1 <value 2>
Third item 2 <value 3>
...
Nth item N-1 <value N>
现在设置一些重要的值。 (这可能会被塞进最终的查询中,但这种方式更易于阅读,并且可能会略微提高性能。)
DECLARE
@ItemCount int
,@FirstValue float
-- How many items to be matched ("N", above)
SELECT @ItemCount = count(*)
from #MatchThis
-- The value of the first item in the search set
SELECT @FirstValue = Value
from #MatchThis
where Position = 0
然后它只是一个查询:
SELECT
pr.Name
,fv.OrderBy -- Required by the Group By, but otherwise can be ignored
from #MatchThis mt
cross join (-- All Segments that match the first value in the set
select ProductId, OrderBy
from Segment
where Value = @FirstValue) fv
inner join Product pr -- Just to get the Product name
on pr.ProductId = fv.ProductId
inner join Segment se
on se.ProductId = fv.ProductId
and se.OrderBy = fv.OrderBy + mt.Position -- Lines them up based on the first value
and se.Value = mt.Value -- No join if the values don't match
group by
pr.Name
,fv.OrderBy
having count(*) = @ItemCount -- Only include if as many segments pulled for this product/segment.OrderBy as are required
我相信这会奏效,但我现在没有时间对其进行详细测试。为了优化性能,除了指示的主键外,您还可以在 Segment.Value 上添加常规索引
关于sql - 查找顺序值的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8011330/