我需要在SQL Server 2016中找到类似的记录,如果我能按照它们的匹配顺序排序结果会很棒。 类似的匹配标准是2个详细信息表。
我的表结构是:
//Basic:
Id Title
1 Title 1
2 Title 2
3 Title 3
4 Title 4
5 Title 5
//Parameters:
Id Title
1 Param 1
2 Param 2
3 Param 3
4 Param 4
5 Param 5
//Values:
Id Value
1 Val 1
2 Val 2
3 Val 3
4 Val 4
5 Val 5
连接表:
BasicId ParameterId ValueId
1 1 2
1 3 1
1 4 5
2 1 1
2 2 4
2 3 2
3 1 2
3 3 1
3 4 4
4 1 2
4 4 2
4 5 2
5 1 1
5 2 5
5 3 3
在我的程序中的某个时刻,我使用参数和值创建新的Basic行(在内存中)。现在我需要知道:
首先,我这样做: 如果所有参数和值都匹配,则 2行相等。 现在我用所有参数和值的ID计算字符串,并将其添加到Basic表。
基本变为:
Id Title EqualString (this comes from connection table)
1 Title 1 1:2;3:1;4:5
2 Title 2 1:1;2:4;3:2
3 Title 3 1:2;3:1;4:4
4 Title 4 1:2;4:2;5:2
5 Title 5 1:1;2:5;3:3
这很好用,因为orderId是由ParameterId ASC定义的,而且我在EqualString列上有索引。在这一点上,我应该说,我的基本表有大约500万条记录并且还在增长。
但对于第二个问题,我不知道如何解决这类问题。
例如:
Input Title X1 1:1;2:4;3:2 100% Title 2
33% Title 5
Input Title X2 1:1;2:4;3:1 66% Title 2
33% Title 5
Input Title X3 1:2;3:1;5:5 66% Title 1
66% Title 3
Input Title X4 1:2;3:1;5:3 66% Title 3
33% Title 5
我使用SQL Server 2016并完全控制安装数据库的计算机 有大约100个参数值来检查它们是否匹配(在上面的例子中只有3个 - 它们用;分开)。
我认为全文搜索不是答案(或者可能是答案),因为我需要2个逗号(例如2:5)之间的完全匹配。
或者我应该采用完全不同的方法而不计算EqualString(很少插入女巫)。
使用案例
我正在构建销售的产品是动态的网页。这意味着,该用户在购买之前对其进行配置
例如:设置高度,宽度,颜色,选择材料......
现在我需要知道这个产品是否已经存在(其他人选择完全相同的参数(宽度,高度,颜色)和值(100,120,绿色)或者这是完全新的产品。
配置的参数在参数表中,值在值表中。
答案 0 :(得分:1)
这是从问题中逐字复制的:
CREATE TABLE #Connection( BasicId INT, ParameterId INT, ValueId INT )
INSERT INTO #Connection
VALUES
( 1, 1, 2 ), ( 1, 3, 1 ), ( 1, 4, 5 ),
( 2, 1, 1 ), ( 2, 2, 4 ), ( 2, 3, 2 ),
( 3, 1, 2 ), ( 3, 3, 1 ), ( 3, 4, 4 ),
( 4, 1, 2 ), ( 4, 4, 2 ), ( 4, 5, 2 ),
( 5, 1, 1 ), ( 5, 2, 5 ), ( 5, 3, 3 )
这是新产品的样本数据
CREATE TABLE #NewConnection( BasicId INT, ParameterId INT, ValueId INT )
INSERT INTO #NewConnection
VALUES
( 10, 1, 2 ), ( 10, 2, 2 ), ( 10, 3, 1 ),
( 11, 1, 1 ), ( 11, 2, 4 ), ( 11, 3, 2 ),
( 12, 1, 0 ), ( 12, 2, 5 ), ( 12, 3, 3 )
SELECT NC.BasicID AS NewBasicID, C.BasicID, C.ParameterId, C.ValueId,
CONVERT( DECIMAL( 5, 0 ), COUNT( C.ParameterId ) OVER( PARTITION BY NC.BasicID, C.BasicID )) / ParamCount * 100 AS MatchStrength
FROM
( SELECT *, COUNT( ParameterId ) OVER( PARTITION BY BasicID ) AS ParamCount
FROM #NewConnection ) AS NC
INNER JOIN #Connection AS C
ON NC.ParameterId = C.ParameterId AND C.ValueId = NC.ValueId
ORDER BY NewBasicID, MatchStrength DESC, C.BasicID, C.ParameterId
#NewConnection
- 包含需要根据现有#Connection
表检查的“新连接”数据ParamCount
- 计算每个“新”BasicID的属性数。需要计算MatchStrength
INNER JOIN
- 在ParameterIDs和ValueIDs上加入与现有连接的“新”连接MatchStrength
- 为每个NC.BasicID,C.BasicID组计算匹配的 ParameterId
和ValueID
组合,然后除以ParamCount
获得匹配的百分比。参考文献:
注意:大型数据集的性能尚未经过测试,但您可能需要以下索引:{parameterID,valueID},{BasicID}
如果要返回不同的匹配BasicID和MatchStrength(无参数ID),请使用以下内容:
SELECT DISTINCT NewBasicID, BasicID, MatchStrength
FROM
( SELECT NC.BasicID AS NewBasicID, C.BasicID, C.ParameterId, C.ValueId,
CONVERT( DECIMAL( 5, 0 ), COUNT( C.ParameterId ) OVER( PARTITION BY NC.BasicID, C.BasicID )) / ParamCount * 100 AS MatchStrength
FROM
( SELECT *, COUNT( ParameterId ) OVER( PARTITION BY BasicID ) AS ParamCount
FROM #NewConnection ) AS NC
INNER JOIN #Connection AS C
ON NC.ParameterId = C.ParameterId AND C.ValueId = NC.ValueId ) AS Matches
ORDER BY NewBasicID, MatchStrength DESC, BasicID