php - MySQL,需要帮助定义多个连接查询以返回完整信息

标签 php mysql join table-relationships

因此,我修改了从 this thread 中学到的查询,但是当我在标签和猫之间进行过滤时,结果并不理想。过滤类别 5 将仅返回类别列表信息,标签将为空,而标签则相反。

    SELECT posts.id,time,title,
        GROUP_CONCAT(IFNULL(cats.id, '') ORDER BY cats.id DESC SEPARATOR '~') as catIdList,
        GROUP_CONCAT(IFNULL(cats.name, '') ORDER BY cats.id DESC SEPARATOR '~') as catNameList,
        GROUP_CONCAT(IFNULL(cats.slug, '') ORDER BY cats.id DESC SEPARATOR '~') as catSlugList,
        GROUP_CONCAT(IFNULL(cats.value, '') ORDER BY cats.id DESC SEPARATOR '~') as catValueList,
        GROUP_CONCAT(IFNULL(tags.id, '') ORDER BY tags.id DESC SEPARATOR '~') as tagIdList,
        GROUP_CONCAT(IFNULL(tags.name, '') ORDER BY tags.id DESC SEPARATOR '~') as tagNameList,
        GROUP_CONCAT(IFNULL(tags.slug, '') ORDER BY tags.id DESC SEPARATOR '~') as tagSlugList,
        GROUP_CONCAT(IFNULL(tags.value, '') ORDER BY tags.id DESC SEPARATOR '~') as tagValueList
    FROM posts
    LEFT JOIN termRelations ON ( posts.id = termRelations.postId )
    LEFT JOIN cats ON ( termRelations.termId = cats.id AND termRelations.termTypeId = 1 )
    LEFT JOIN tags ON ( termRelations.termId = tags.id AND termRelations.termTypeId = 0 )
    WHERE ( ( IFNULL(tags.id, '') = '4' ) )
    GROUP BY posts.id ORDER BY time DESC

IFNULL() 用于处理不存在的条目。上面的查询将返回:

    (
        [id] => 15
        [time] => 0
        [title] => post 15
        [catIdList] => 
        [catNameList] => 
        [catSlugList] => 
        [catValueList] => 
        [tagIdList] => 4
        [tagNameList] => tagname
        [tagSlugList] => tagname
        [tagValueList] => 
    )

    (
        [id] => 16
        [time] => 0
        [title] => post 16
        [catIdList] => 
        [catNameList] => 
        [catSlugList] => 
        [catValueList] => 
        [tagIdList] => 4
        [tagNameList] => tagname
        [tagSlugList] => tagname
        [tagValueList] => 
    )

虽然没有 WHERE ( ( IFNULL(tags.id, '') = '4' ) ) 结果将是(以及所有其他帖子,因为它没有被过滤到这个标签,当然):

    (
        [id] => 15
        [time] => 0
        [title] => post 15
        [catIdList] => 
        [catNameList] => 
        [catSlugList] => 
        [catValueList] => 
        [tagIdList] => 4
        [tagNameList] => tagname
        [tagSlugList] => tagname
        [tagValueList] => 
    )

    (
        [id] => 16
        [time] => 0
        [title] => post 16
        [catIdList] => 5~~
        [catNameList] => Movies~~
        [catSlugList] => movies~~
        [catValueList] => ~~
        [tagIdList] => 4~1~
        [tagNameList] => tagname~sand~
        [tagSlugList] => tagname~sand~
        [tagValueList] => ~~
    )

这当然是我想要的 - 所有相关信息!

表格是:

  1. termRelations 包含帖子 ID 和术语 ID,其中 termTypeId 区分猫和标签表。
  2. cats 包含术语 ID 和类别信息(名称、slug、parentId 等)
  3. tags 包含术语 ID 和标签信息(名称、slug 等)
  4. posts 包含帖子信息(标题、时间、正文等)

termRelations 的目的是将标签和类别绑定(bind)到帖子。此查询的目的是返回过滤后的结果(我希望用户能够查看具有特定标签和特定类别的帖子。)同时仍保留完整信息。

是否可以通过将 catstags 表合并到 terms 中来解决这个问题?

我希望我知道怎么做,但在这一点上我几乎在这方面遇到了心理障碍。所以,帮助不大 :)?谢谢!!

最佳答案

WHERE 更改为带有子查询的 EXIST:

SELECT posts.id,time,title,
    GROUP_CONCAT(IFNULL(cats.id, '') ORDER BY cats.id DESC SEPARATOR '~')
      AS catIdList,
    GROUP_CONCAT(IFNULL(cats.name, '') ORDER BY cats.id DESC SEPARATOR '~') 
      AS catNameList,
    GROUP_CONCAT(IFNULL(cats.slug, '') ORDER BY cats.id DESC SEPARATOR '~') 
      AS catSlugList,
    GROUP_CONCAT(IFNULL(cats.value, '') ORDER BY cats.id DESC SEPARATOR '~') 
      AS catValueList,
    GROUP_CONCAT(IFNULL(tags.id, '') ORDER BY tags.id DESC SEPARATOR '~') 
      AS tagIdList,
    GROUP_CONCAT(IFNULL(tags.name, '') ORDER BY tags.id DESC SEPARATOR '~') 
      AS tagNameList,
    GROUP_CONCAT(IFNULL(tags.slug, '') ORDER BY tags.id DESC SEPARATOR '~') 
      AS tagSlugList,
    GROUP_CONCAT(IFNULL(tags.value, '') ORDER BY tags.id DESC SEPARATOR '~') 
      AS tagValueList
FROM posts
LEFT JOIN termRelations ON ( posts.id = termRelations.postId )
LEFT JOIN cats 
  ON ( termRelations.termId = cats.id AND termRelations.termTypeId = 1 )
LEFT JOIN tags 
  ON ( termRelations.termId = tags.id AND termRelations.termTypeId = 0 )
WHERE EXISTS
      ( SELECT *
        FROM termRelations 
        WHERE termRelations.termId = '4'
          AND termRelations.termTypeId = 0
          AND posts.id = termRelations.postId
      )
GROUP BY posts.id 
ORDER BY time DESC

关于php - MySQL,需要帮助定义多个连接查询以返回完整信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8720369/

相关文章:

php - 从 PHP shell_exec 返回 XML 输出的方法?

MySQL:删除所有超过 10 分钟的行

python - 如何在 pandas 中加入两个 DF 并选择我想要返回的列?

javascript - 根据自动完成文本框中插入的值动态添加下拉列表

php - 如何防止 PHP 中的 SQL 注入(inject)?

php - Laravel 在 Controller 函数中添加中间件

mysql - 无法使用命令行中指定的密码登录mysql

PHP、MySQL : question on how to "sync" two databases

MySql:如果用户具有特定角色则排除用户

c# - 根据多个条件外部连接两个数据表