Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 通过链接表的多条件联接_Mysql - Fatal编程技术网

Mysql 通过链接表的多条件联接

Mysql 通过链接表的多条件联接,mysql,Mysql,请容忍我,这需要大量的预先信息来解释我正在尝试做什么。我已经尽可能地把它泛化,使事情更清楚。在一个查询中,我希望拉出一个与另一个表中链接的标记相匹配的页面列表,这些标记是分组的。我希望使用项目的文本表示,而不是它的id,但如果没有其他方法,我可以做2个预先查询,以获得标记id和标记组id-只是希望不必这样做 数据库模式: +-----------------------------------+ | taggroups | +-----------

请容忍我,这需要大量的预先信息来解释我正在尝试做什么。我已经尽可能地把它泛化,使事情更清楚。在一个查询中,我希望拉出一个与另一个表中链接的标记相匹配的页面列表,这些标记是分组的。我希望使用项目的文本表示,而不是它的id,但如果没有其他方法,我可以做2个预先查询,以获得标记id和标记组id-只是希望不必这样做

数据库模式:

+-----------------------------------+
| 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)
此外,哪些表应该有索引,哪些索引应该用于优化?

我会这样做:

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
子句中,这对我来说似乎更整洁

在重新键入此查询时,我发现您在某个地方使用了标记id,我认为该标记id应该是标记组id,因此我对其进行了更改,但很抱歉现在无法再次看到它

我还担心选择标准——如果一个苹果碰巧不是水果呢?显然,在这种情况下是这样的,事实上也是这样:-),但我认为您应该只在查询中指定水果名称,而不是水果和组名称,并让数据库自己对其进行排序

另外,为什么对标记、标记到页面和标记组使用
内部联接
,而对页面使用外部联接?当然,如果没有页面,您最好不返回任何行,而不是返回一行,半满为空

我只为id列编制索引

只是我的2便士,真的

编辑

我已经在上设置了一个演示。我更改了
SELECT
列表中的别名后,您的工作正常。我的查询工作得不太好:-(。我的别名也有同样的问题,一旦修复了它们,查询将返回同一行两次

我从头开始重新写了一遍

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';
而且效果很好

设置此演示时,我突然想知道为什么您要将
taggroup\u id
保存在
tags\u to\u pages
表中。我在SQL和数据库方面是“自学”的(将其翻译为:“我边做边补,依靠做‘工作’的事情,相信直觉来找出什么是‘正确的’)但是这不是打破了标准化的想法吗?
标记
标记组
之间的联系不应该只通过
标记
表中的
标记组id
列来定义吗?也许真正了解数据库的人会来纠正我


最后,我不知道为什么PHPMyAdmin在您尝试查询时挂断了电话。祝您好运!

正如您可能从上面的货币单位猜到的,我在英国,时间已经很晚了,所以我现在要睡觉了-我会在上午回复任何评论-即10个小时的时间。祝您好运。谢谢nurd,您刚刚更改了查询的结构还是还有它背后的逻辑。例如,它是以不同的方式做同样的事情吗?因为我一开始无法让我的查询工作。太慢了,睡不着觉!我改为加入taggroupid而不是某个地方的tag|id:-|当查询“无法工作”时,你遇到了什么问题?它是什么也不返回,还是返回“错误的东西”?在PHPMyAdmin中,它只是坐在那里处理,没有错误,没有结果。正常查询会立即返回。也运行本地查询,因此这不是内存或大型数据库问题。非常感谢,看起来这工作得很好。您是对的,不需要额外的组id-删除它。还感谢您发现SQLFIDDLE,这是一个很棒的实用程序.