【问题标题】:Advance query. Rank most related fields in mysql提前查询。对mysql中最相关的字段进行排名
【发布时间】:2012-07-21 12:01:23
【问题描述】:

假设我们有一个这样的数据库:

Project_tbl:

----------------- 编号 |项目名 ----------------- 1 |一种 2 |乙 3 | C -----------------

personel_project_tbl:

-------------------- 用户 ID |项目编号 -------------------- 1 | 1 2 | 2 3 | 1 3 | 2 2 | 3 --------------------

instrument_project_tbl:

-------------------------- 仪器ID |项目编号 -------------------------- 1 | 1 1 | 2 2 | 2 2 | 1 1 | 3 --------------------------

现在,我需要对项目列表进行排序,并根据它们与项目 A 的相似性对它们进行排名。

例如:

A 和 B 在 3 个用户中有 1 个共同用户,在 2 个仪器中有 2 个仪器,因此它们的相似度排名为 (1/2 + 2/2) / 2 = 75%

A 和 C 没有共同的用户,但有 1 比 2 仪器,所以它将是 (1/2)/2 = 25%

所以B比be更相似,输出应该是

-------------- 项目 |秩 -------------- 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(n2) 并且索引选择也会花费 O(log n) 这不会'买不起。

您有什么想法是完全在 MySQL 中完成,还是以更好更快的方式完成?

********更多信息和说明:**

  1. 我仅限于 PHP 和 MySQL。

  2. 这只是一个例子,在我的实际项目中,表有 20 多个表,因此该解决方案应该具有高性能

  3. 这个问题是这个问题的补充问题:Get the most repeated similar fields in MySQL database 如果你的解决方案可以以某种方式对他们俩都使用或应用(不知何故),那就太好了。 我想将相关项目的价值与项目的相似性相乘以获得最佳选择...

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


感谢您的智慧回答,如果您能对情况有所了解,我们将不胜感激

【问题讨论】:

  • 我想得到这个计算。 A 和 B 在 3 个用户中有 1 个共同用户,在 2 个仪器上有 2 个仪器,所以他们的相似度排名是 (1/2 + 2/2) / 2 = 75% ...应该是 (1/3+2 /2)/2 =67% ?
  • @JoeGJoseph 超过项目 A 的 2 个用户

标签: php mysql sql inner-join


【解决方案1】:

你可以做到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(n2) 复杂性提一下,因为您必须检查所有数据。

【讨论】:

  • 谢谢兄弟,太棒了。我可以为示例数据库运行它并且工作正常,需要检查我的实际数据库并返回给你。无论如何,你能检查我的另一个问题吗?这个答案需要用于stackoverflow.com/questions/11538409/…...在这里我找到了最相似的项目,在那里我找到了关于项目关系排名的适当项目。如果您需要更多详细信息,请告诉我
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-21
  • 1970-01-01
  • 2020-08-31
  • 2011-09-24
  • 1970-01-01
  • 2019-03-30
  • 2018-02-22
相关资源
最近更新 更多