【发布时间】:2016-10-24 23:27:27
【问题描述】:
假设我有以下表格/字段:
CREATE TABLE tbl_projects (
prjc_id int PRIMARY KEY
)
CREATE TABLE tbl_project_requirements (
preq_prjc_id int -- Foreign key to tbl_projects
preq_type_id int -- A standardized requirement category
)
给定一个特定项目,我想找到具有几乎类似需求类别的其他项目......或者假设他们的需求至少有 75% 重叠.
我可以做到以下几点:
DECLARE @prjc_id int = 1
CREATE TABLE #project_reqs (type_id int)
INSERT INTO #project_reqs
SELECT preq_req_type_id
FROM tbl_project_requirements
WHERE preq_prjc_id = @prjc_id
SELECT prjc_id
FROM tbl_projects
CROSS APPLY (
SELECT CASE
WHEN COUNT(*) = 0 THEN 0.0
ELSE COALESCE(SUM(CASE WHEN type_id = prjc_type_id THEN 1.0 ELSE 0.0 END), 0.0)
/ CONVERT(float, COUNT(*))
END AS similarity
FROM #project_reqs
FULL OUTER JOIN (
SELECT prjc_type_id
FROM tbl_project_requirements
WHERE preq_prjc_id = prjc_id
) reqs ON preq_type_id = type_id
) reqs
WHERE prjc_id != @prjc_id
AND similarity >= 0.75
在上面,我将匹配需求类别除以每两个项目之间的总不同需求类别,以获得重叠百分比。
虽然这行得通,但我感觉到代码异味,并且认为这不会很好地扩展。是否有任何方法可以有效地计算两个项目之间子记录的重叠?也许某种部分哈希匹配或...?
更新
我想我找到了一个高效的解决方案:
DECLARE @prjc_id int = 1
CREATE TABLE #project_reqs (type_id int)
INSERT INTO #project_reqs
SELECT preq_req_type_id
FROM tbl_project_requirements
WHERE preq_prjc_id = @prjc_id
DECLARE @project_req_count float
SELECT @project_req_count = COUNT(*)
FROM #project_reqs
CREATE TABLE #projects (
pj_prjc_id int,
pj_func_count float,
pj_func_common float
)
INSERT INTO #projects
SELECT preq_prjc_id,
COUNT(*),
COUNT(type_id)
FROM tbl_project_requirements
LEFT OUTER JOIN #project_reqs
ON preq_type_id = type_id
GROUP BY preq_prjc_id
HAVING COUNT(type_id) != 0
SELECT pj_prjc_id
FROM #projects
WHERE pj_func_common / (pj_func_count + @project_req_count - pj_func_common) >= 0.75
DROP TABLE #project_reqs
DROP TABLE #projects
【问题讨论】:
标签: sql sql-server hash hashset