请耐心等待,这需要很多前期信息来解释我想要做的事情。我试图尽可能地将其泛化以使事情更清楚。在一个查询中,我希望提取一个与另一个表中链接的标签匹配的页面列表,这些标签是分组的。我希望使用项目的文本表示而不是它的id,但如果没有别的我可以做2个前面的查询来获取tag_id和taggroup_id - 只是希望不必这样做。
DB Schema:
+-----------------------------------+
| taggroups |
+------------------+----------------+
| taggroup_id | group_name |
+------------------+----------------+
| 1 | fruits |
+------------------+----------------+
+-----------------------------------------------+
| tags |
+-------------+-----------------+---------------+
| tag_id | taggroup_id | tag_name |
+-------------+-----------------+---------------+
| 1 | 1 | apple |
| 2 | 1 | orange |
| 3 | 1 | grape |
+-------------+-----------------+---------------+
+--------------------------------------+
| pages |
+------------------+-------------------+
| page_id | title |
+------------------+-------------------+
| 99 | Doctor a day |
+------------------+-------------------+
+--------------------------------------------------+
| tags_to_pages |
+------------+----------+---------------+----------+
| join_id | tag_id | taggroup_id | page_id |
+------------+----------+---------------+----------+
| 1 | 1 | 1 | 99 |
| 2 | 2 | 1 | 99 |
+------------+----------+---------------+----------+
测试查询: 到目前为止,似乎无法让它发挥作用。
SELECT
pages.*, tags.tag_name, taggroups.group_name
FROM
tags_to_pages
INNER JOIN taggroups as grp ON (
grp.group_name = 'fruits'
AND
tags_to_pages.taggroup_id = grp.taggroup_id
)
INNER JOIN tags as val ON (val.tag_name = 'apple' AND tags_to_pages.tag_id = val.tag_id)
LEFT JOIN pages ON (tags_to_pages.page_id = pages.page_id)
此外,哪些表应该有索引以及索引应该用于优化?
答案 0 :(得分:0)
我这样做:
SELECT
pages.*, tags.tag_name, taggroups.group_name
FROM
tags_to_pages
JOIN taggroups AS grp ON grp.taggroup_id = tags_to_pages.taggroup_id
JOIN tags AS val ON val.taggroup_id = grp.taggroup_id
JOIN pages ON tags_to_pages.page_id = pages.page_id
WHERE
grp.group_name='fruits'
AND val.tag_name = 'apple'
这不是 与您所拥有的不同,但我将加入条件放在JOIN
子句和WHERE
子句中的选择条件中,这对我来说似乎更整洁。
在重新输入此查询时,我发现您在某个地方使用了tag_id,我认为应该是taggroup_id,所以我更改了它,但我很遗憾现在无法再看到它。
我也担心选择标准 - 如果苹果没有成为水果怎么办?显然它是在这种情况下,实际上是在实际上:-),但我认为你应该只在查询中指定水果名称,而不是水果和组名,并让数据库为自己排序。
另外,为什么对标签,tags_to_pages和taggroups以及页面的OUTER JOIN使用INNER JOIN
?当然,如果没有页面,你最好不要返回任何行而不是一行,在NULLS上半满?
我只会为id列编制索引。
真的是我的2p值。
修改强>
我已在www.sqlfiddle.com上设置了此演示。我更改SELECT
列表中的别名后,original query工作正常。我的attempt above效果不是很好:-(。我对别名有同样的问题,一旦我修复它们,查询就会返回同一行两次。
我再次从头开始重写它
SELECT pages.*, tags.tag_name, taggroups.group_name
FROM pages
JOIN tags_to_pages AS ttp ON ttp.page_id = pages.page_id
JOIN tags ON tags.tag_id = ttp.tag_id
JOIN taggroups ON taggroups.taggroup_id = ttp.taggroup_id
WHERE taggroups.group_name = 'fruits' AND tags.tag_name='apple';
它工作正常link。
设置此演示,让我想知道为什么要在taggroup_id
表中保存tags_to_pages
。我在SQL和数据库中“自学成才”(将其翻译为:“我随身携带,依靠做”工作“并相信直觉来找出'正确'的东西”)但不是这打破了正常化的想法吗? tags
和taggroups
之间的关联不应仅通过taggroup_id
表中的tags
列进行定义吗?也许真正了解数据库的人会出现并让我正确。
最后,我不知道为什么PHPMyAdmin在您尝试查询时会挂起。祝你好运!