sql - 查找顺序值的有效方法

标签 sql sql-server sql-server-2005 sql-server-2008 tsql

每个“产品”最多可以有 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/

相关文章:

c# - 如何过滤 SQL Server 中所有现有存储过程的输出?

sql - 在表上创建 View 可以提高 sql 2000 的查询性能吗?

sql - 使用和不使用连接的查询性能

sql-server - sql server 2008 存储过程,不能在单引号中使用变量

mysql - 选择多个 mysql 列

java - 使用 Java 检查 SQL 服务器是否在线

sql-server - SQL Server : Put stored procedure result set into a table variable without specifying its schema

c# - 一个窗口窗体中的两个数据 GridView = 无法将数据保存到第二个数据 GridView

sql - 在所有数据库中搜索存储过程/函数

sql-server-2005 - 更新表 SET 字段