【问题标题】:MySQL Need help defining SQL to remove unwanted rowsMySQL 需要帮助定义 SQL 以删除不需要的行
【发布时间】:2012-01-01 05:10:53
【问题描述】:

所以该项目正在用 PHP 制作一个简单的 CMS。您有帖子、类别和标签。它将在一个数据库中处理数百万个帖子、数百万个标签和类别。

问题: 最理想的情况是,您希望能够选择 30 个必须在类别 5 和标签 1 和 2 下的帖子。您希望在尽可能少的查询中完成...

termRelations 包含帖子 ID 和术语 ID,termTypeId 区分猫和标签表。
cats 包含术语 ID 和类别信息(名称、 slug 等)
tags 包含术语 ID 和标签信息(名称、slug 等)

cats 和 tags 是单独的表,因此可以加快生成类别列表/更单独地定义它们。

SELECT DISTINCT *
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 cats.id =5
OR tags.id =2
OR tags.id =1
LIMIT 0 , 30

在这种情况下,它为一篇文章返回 3 行,前两行添加了标签字段,最后两行添加了类别字段。

我不需要这些信息来使用(因为在一行中涉及多个标签或类别时这似乎是不可能的。也许不是?),我只需要在这三个术语下抓取帖子。不过,如果我可以通过一个查询获得类别和标签信息,那将是最佳的。

谢谢。这让我的大脑很混乱。如果我做错了什么并且您知道一种更有效的方法,那么我很乐意重新构建数据库。

【问题讨论】:

  • 我能看到的第一个错误是 WHERE cats.id =5 OR tags.id =2 OR tags.id =1...Make it WHERE cats.id =5 AND( tags.id =2或 tags.id =1)
  • 不幸的是,我尝试了这个,结果没有行,所以我切换到 OR。
  • 这意味着你的查询是错误的..anyways..temme 关于这个“术语”..一个帖子有多个术语吗??
  • 术语只是标签或类别的另一个词。我分离了标签和类别,但它们只是术语。每个帖子可能有很多标签,最多可能有 2 个类别。我需要相应地过滤帖子! IE。您希望在“食品”和“消耗品”类别下发布带有“文章”标签的帖子。

标签: php mysql performance select left-join


【解决方案1】:

DISTINCT 适用于 SELECT 中的所有列,因此您是否正在选择所有内容,它将返回每个不同的行,而不仅仅是不同的帖子。为了解决这个问题,您可以从帖子表中选择数据,然后对其进行区分,即

SELECT DISTINCT posts.*

但您也说过,如果可能,您也希望获得帖子和猫的信息。执行此操作并在每个帖子中保留一行的一种方法是使用 GROUP_CONCAT,因此您的查询可能会以这样的方式结束。

SELECT 
   posts.*,
   GROUP_CONCAT(cats.id SEPARATOR ',') as catsList,
   GROUP_CONCAT(tags.id SEPARATOR ',') as tagsList
FROM posts
INNER JOIN termRelations ON ( posts.id = termRelations.postId )
LEFT JOIN cats ON ( termRelations.termId = cats.id AND termRelations.termTypeId = 1 AND cats.id =5 )
LEFT JOIN tags ON ( termRelations.termId = tags.id AND termRelations.termTypeId = 0 AND 
   (tags.id =2
   OR tags.id =1)
)
GROUP BY posts.id
LIMIT 0 , 30

我对您的原始查询进行了其他一些更改,例如将第一个联接更改为 INNER JOIN 并将 cat/tags 过滤器添加到相关表的 JOIN 条件中。

ps 当您说您有单独的表用于猫和标签以加快生成列表时,您可能会发现正确索引的表会同样快并且还可以简化您的代码。

【讨论】:

  • 就是这样。我知道有办法,你已经启发了我:D!而且我想我会在合并猫和标签表时听取您的建议 - 我最初将它们合并为“术语”,是时候重新编码了,我同意,它最终会简化。谢谢。
  • 这就是 SO 的用途 ;-) 您可能想对我的回答投赞成票并接受它。
  • 声望不够,还需要7个,哈哈。将不得不回到它:)
猜你喜欢
  • 2012-09-26
  • 1970-01-01
  • 2015-03-09
  • 2021-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-29
  • 2018-07-02
相关资源
最近更新 更多