MySQL相关的'项目'查询

时间:2012-11-22 12:54:27

标签: mysql sql

请考虑以下项目表:

Project:
  table: project
  manyToMany:
    themes:
      targetEntity: Theme
      inversedBy: projects
      joinTable:
        name: project_theme
        joinColumns:
          project_id:
            referencedColumnName: id
        inverseJoinColumns:
          theme_id:
            referencedColumnName: id
    platforms:
      targetEntity: Platform
      joinTable:
        name: project_platform
        joinColumns:
          project_id:
            referencedColumnName: id
        inverseJoinColumns:
          platform_id:
            referencedColumnName: id
  manyToOne:
    client:
      targetEntity: Client

正如你所看到的,一个项目有三个关系;主题通过project_theme连接表,平台通过project_platform表,客户端通过client_id列
我正在尝试生成一个查询,它将查找所有相关项目 - 具有相同主题,平台或客户的项目 - 并按“得分”排序。

例如:

Project A:
  Themes: 18, 19
  Platforms: 1, 4
  Client: 22

查找项目A的相关项目..

Project D:
  Themes: 18, 19
  Platforms: 1, 4
  Client: 22
Score: 5
Project G:
  Themes: 18, 21
  Platforms: 3, 4
  Client: 22
Score: 3
Project B:
  Themes: 8, 21
  Platforms: 2, 4
  Client: 1
Score: 1

我非常感谢为此编写MySQL查询的助手。以下我一直在努力奋斗一段时间 - 但我可能还有几英里的距离:

SELECT 
    `project`.*,
    GROUP_CONCAT(`project_theme`.`theme_id`) as themes,
    GROUP_CONCAT(`project_platform`.`platform_id`) as platforms,
    `project`.`client_id` as client
FROM `project`
LEFT JOIN `project_theme` ON `project`.`id` = `project_theme`.`project_id`
LEFT JOIN `project_platform` ON `project`.`id` = `project_platform`.`project_id`
GROUP BY `project`.`id`

非常感谢您的任何帮助 皮特

2 个答案:

答案 0 :(得分:0)

我在平板电脑上,所以我会很简短。将它们视为三个独立的查询并将它们结合起来。当我有一个键盘时,我会用sql回来。

答案 1 :(得分:0)

感谢你提示Marlin,在阅读了Advance query. Rank most related fields in mysql并进行了一些实验之后,我想我可能已经破解了它......

SELECT 
    p.*,
    (
        IFNULL(themes.matches, 0) + IFNULL(platforms.matches, 0) + IFNULL(clients.matches, 0)
    ) as score
FROM `project` p
LEFT JOIN (
    SELECT t2.project_id, COUNT(*) as matches FROM `project_theme` t1, `project_theme` t2
    WHERE 
      t1.theme_id = t2.theme_id AND t1.project_id = 1
      GROUP BY t2.project_id
) themes ON p.id = themes.project_id
LEFT JOIN (
    SELECT f2.project_id, COUNT(*) as matches FROM `project_platform` f1, `project_platform` f2
    WHERE 
      f1.platform_id = f2.platform_id AND f1.project_id = 1
      GROUP BY f2.project_id
) platforms ON p.id = platforms.project_id
LEFT JOIN (
    SELECT p2.id, COUNT(*) as matches FROM `project` p1, `project` p2
    WHERE 
      p1.client_id = p2.client_id AND p1.id = 1
      GROUP BY p2.id
) clients ON p.id = clients.id
GROUP BY p.`id`
HAVING score > 0
ORDER BY score DESC;