2012-07-23 74 views
2

假设我们有一个这样的数据库:高级查询。在MySQL中排名最相关领域

Project_tbl

 
----------------- 
id | Project_name 
----------------- 
1 | A 
2 | B 
3 | C 
----------------- 

personel_project_tbl

 
-------------------- 
user_id | Project_id 
-------------------- 
1  | 1 
2  | 2 
3  | 1 
3  | 2 
2  | 3 
-------------------- 

instrument_project_tbl

 
-------------------------- 
instrument_id | Project_id 
-------------------------- 
1    | 1 
1    | 2 
2    | 2 
2    | 1 
1    | 3 
-------------------------- 

现在,我需要排序的项目清单,并就其相似的项目A.

例如对他们进行排名:

A和B具有共同1个用户在2个仪器上的3个用户和2个仪器上,因此它们的相似性排名是(1/2 + 2/2)/ 2 = 75%。A和C没有共同的用户,但是具有1个2个以上的仪器,所以它将是(1/2)/ 2 = 25%

所以B比更类似于是和输出应该是

 
-------------- 
Project | Rank 
-------------- 
2  | 75 
3  | 25 

这是第一个解决方案来到我的脑海...
如果我在PHP和MySQL做它,它会是这样的:

for all tables as table_x 
    for all projects (except A) as prj_y 
     unique = (Select distinct count(items) from table_x where project is A) 
     count += (Select distinct count(items) from table_x 
        where project is prj_x and items are in 
        (select distinct items from table_x where project is a) 
       )/unique 

所以复杂性将是O(ñ ),并编制索引还选择将花费O(日志n),这将不会负担得起。

你有什么想法在MySQL中完全做到或以更好更快的方式做到这一点吗?

********更多信息和注意事项:**

  1. 我仅限于PHP和MySQL。

  2. 这只是一个例子,在我的真实项目中,表格超过20个表格,所以解决方案应该有高性能

  3. 这个问题是这个问题的补充问题:Get the most repeated similar fields in MySQL database如果年终解决方案可以用于或以某种方式应用于他们两个(以某种方式)这将是伟大的。 我要乘以项目的相似性,以获得最佳的选择相关项目的价值...

总之,这两个问题将:获得最相关的项目,让所有的类似项目项目并找到当前项目中与当前项目类似的最相似的项目!哟


感谢您的知识产权的答案,它真的很感激,如果你能在情况

+0

我知道这个计算。 A和B在2个仪器上共有3个用户和2个仪器的1个用户,因此它们的相似性排名是(1/2 + 2/2)/ 2 = 75%...应该是(1/3 + 2/2)/ 2 = 67%? – 2012-07-23 09:22:58

+0

@JoeGJoseph超过2个项目的用户A – 2012-07-23 10:28:48

回答

0

一些启发你可以做到这一点this way

SET @Aid = (SELECT id 
      FROM Project_tbl 
      WHERE Project_name = 'A'); 

SELECT P.id 
    , (IFNULL(personel.prop, 0) + 
    IFNULL(instrument.prop, 0) 
    )/2*100 Rank 
    , personel.prop AS personell 
    , instrument.prop AS instrument 
FROM Project_tbl P 
LEFT JOIN 
    (SELECT B.Project_id pid, COUNT(*)/C.ref prop 
    FROM personel_project_tbl A, 
     personel_project_tbl B, 
     (SELECT COUNT(*) AS ref 
      FROM personel_project_tbl 
      WHERE Project_id = @Aid 
     ) AS C 
    WHERE A.user_id = B.user_id 
    AND A.Project_id = @Aid 
    GROUP BY B.Project_id 
) personel ON P.id = personel.pid 
LEFT JOIN 
    (SELECT B.Project_id pid, COUNT(*)/C.ref prop 
    FROM instrument_project_tbl A, 
     instrument_project_tbl B, 
     (SELECT COUNT(*) AS ref 
      FROM instrument_project_tbl 
      WHERE Project_id = @Aid 
     ) AS C 
    WHERE A.instrument_id = B.instrument_id 
    AND A.Project_id = @Aid 
    GROUP BY B.Project_id 
) instrument ON P.id = instrument.pid 
WHERE P.id <> @Aid 
ORDER BY Rank DESC 

的想法是有每个表的一个子查询,并且每个这些子查询都将项目ID映射到给定表的对应比率。

我对性能一无所知。您必须尝试查看其速度是否足以满足您的需求,但正如我所看到的,无法击败您提到的O复杂性,因为您必须检查所有数据。

+0

感谢兄弟,这真棒。我可以运行它为一个示例数据库和工作正常,需要检查我的实际分贝,并会回到你。无论如何,你能检查我的其他问题是否好?这个答案需要用于http://stackoverflow.com/questions/11538409/get-the-most-repeated-similar-fields-in-mysql-database ...在这里我找到了最相似的项目,我发现关于项目关系排名的适当项目。让我知道你是否需要更多细节 – 2012-07-26 03:15:51