MySQL二级查询性能过于强烈

时间:2013-08-05 20:35:11

标签: php mysql sql activerecord

我有一个查询,我想根据另一个表中所选项目的ID从另一个表中提取ID。我目前正在使用基于我从主查询获得的结果的附加查询来执行此操作。它导致了许多其他查询。有没有办法将其压缩为1个查询?

SELECT music.id,
       SUM(linked_tags.weight) AS total_weight
FROM (music)
INNER JOIN linked_tags ON linked_tags.track_id = music.id
AND linked_tags.tag_id IN (7,56,59)
GROUP BY music.id
ORDER BY total_weight DESC

然后,附加查询来自通过foreach循环运行主查询的结果,其中2713是音乐表中项目的ID。

SELECT tag_id,
       weight
FROM (linked_tags)
JOIN tags_en ON tags_en.id = linked_tags.tag_id
WHERE track_id = '2713'

这导致了这个对象,其中all_tags是来自第二个查询的数据:

[id] => 1500
[name] => Some Track Name
[total_weight] => 10
[all_tags] => Array
    (
        [0] => 20
        [1] => 28
        [2] => 4
        [3] => 13
        [4] => 16
        [5] => 7
        [6] => 42
        [7] => 56
        [8] => 61
    )

有没有办法将这一切全部拉入1个查询?

1 个答案:

答案 0 :(得分:1)

您可以使用join直接合并它们:

select tag_id, weight
from (SELECT music.id,
             SUM(linked_tags.weight) AS total_weight
      FROM music join
           linked_tags
           ON linked_tags.track_id = music.id AND linked_tags.tag_id IN (7,56,59)
      GROUP BY music.id
     ) m join
     linked_tags
     on m.id = linked_tags.track_id join
     tags_en
     ON tags_en.id = linked_tags.tag_id;

编辑:

如果我正确理解了查询,您正试图获取“{1}}集合中包含一个或多个标记的”轨道“(或”音乐“)上的所有标记。 ,你想得到这三个标签的权重之和。

如果您不介意在逗号分隔的列表中包含标记,则可以一次完成此操作:

(7,56,59)

然后,您必须在应用程序层解析 SELECT m.id, SUM(case when lt.tag_id IN (7,56,59) then lt.weight end) AS total_weight, sum(lt.tag_id IN (7, 56, 59)) as NumSpecialTags, group_concat(lt.tag_id) as AllTags FROM music m join linked_tags lt ON lt.track_id = m.id GROUP BY m.id having NumSpecialTags > 0 order by total_weight desc; 列表。