Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.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
Php MySQL需要帮助定义SQL来删除不需要的行_Php_Mysql_Performance_Select_Left Join - Fatal编程技术网

Php MySQL需要帮助定义SQL来删除不需要的行

Php MySQL需要帮助定义SQL来删除不需要的行,php,mysql,performance,select,left-join,Php,Mysql,Performance,Select,Left Join,因此,该项目正在用PHP制作一个简单的CMS。您有帖子、类别和标签。它将在一个数据库中处理数以百万计的帖子,以及数以百万计的标签和类别 问题是: 最理想的情况是,您希望能够选择30篇文章,这些文章必须位于类别5和标签1和2之下。您希望在尽可能少的查询中完成它 术语关系包含post ID和术语ID,termTypeId用于区分cats和tags表。 cats包含术语ID和类别信息(名称、slug等)。 标记包含术语ID和标记信息(名称、slug等) CAT和标签是分开的表,因此可以加快生成类别列表

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

问题是: 最理想的情况是,您希望能够选择30篇文章,这些文章必须位于类别5和标签1和2之下。您希望在尽可能少的查询中完成它

术语关系包含post ID和术语ID,termTypeId用于区分cats和tags表。
cats包含术语ID和类别信息(名称、slug等)。
标记包含术语ID和标记信息(名称、slug等)

CAT和标签是分开的表,因此可以加快生成类别列表/更分开地定义它们

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行,前两行添加了标记字段,最后一行添加了类别字段

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


谢谢。这是在折磨我的大脑。如果我做错了什么,而您知道一种更有效的方法,那么我很乐意重新构建数据库。

DISTINCT对SELECT中的所有列都有效,因此您选择了所有内容,它将返回每个不同的行,而不仅仅是不同的帖子。要解决这个问题,您只需从posts表中选择数据,然后将其区分开来,即

SELECT DISTINCT posts.*
但你也说过,如果可能的话,你也会想要帖子和猫的信息。要做到这一点并在每篇文章中保留一行,一种方法是使用,这样您的查询可能会以类似的方式结束

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
我对原始查询做了一些其他更改,比如将第一个连接更改为内部连接,并将cats/tags过滤器添加到相关表的连接条件中


ps当你说你有单独的猫和标签表来加速列表的生成,您可能会发现,一个正确索引的表将同样快速,也将简化您的代码。

DISTINCT适用于SELECT中的所有列,因此您选择了所有内容,它将返回每个不同的行,而不仅仅是不同的POST。要解决这个问题,您只需从posts表中选择数据,然后将其区分开来,即

SELECT DISTINCT posts.*
但你也说过,如果可能的话,你也会想要帖子和猫的信息。要做到这一点并在每篇文章中保留一行,一种方法是使用,这样您的查询可能会以类似的方式结束

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
我对原始查询做了一些其他更改,比如将第一个连接更改为内部连接,并将cats/tags过滤器添加到相关表的连接条件中


ps当你说你有单独的表用于CAT和tags来加速列表的生成时,你可能会发现一个正确索引的表也会同样快,并且会简化你的代码。

我看到的第一个错误是cats.id=5或tags.id=2或tags.id=1…将它设为cats.id=5和(tags.id=2或tags.id=1)不幸的是,我尝试了这个方法,结果没有行,所以我切换到了或。这意味着你的查询是错误的。不管怎样,请告诉我这个“术语”。一篇文章有多个术语吗?术语只是标签或类别的另一个词。我将标签和类别分开,但它们只是术语。每个帖子可能有很多标签,最多可能有两个类别。我需要相应地过滤帖子!例如,你想要在“食品”和“消耗品”类别下贴上标签“物品”。我能看到的第一个错误是cats.id=5或tags.id=2或tags.id=1…把它放在cats.id=5和(tags.id=2或tags.id=1)的位置。不幸的是,我尝试了这个方法,结果没有行,所以我切换到了或。这意味着你的查询是错误的。不管怎样,请告诉我这个“术语”…一篇文章是否有多个术语?术语只是标签或类别的另一个词。我将标签和类别分开,但它们只是术语。每个帖子可能有很多标签,最多可能有两个类别。我需要相应地过滤帖子!你想要在“食品”和“消耗品”类别下贴上标签“物品”的帖子。就是这样。我知道有一种方法,你也启发了我:D!我想我会采纳你的建议,合并猫表和标签表——我最初将它们合并为“术语”,是时候重新编码了,正如我所同意的,它最终会简化。谢谢。这就是为什么在这里;-)你可能想在接受我的答案的同时投票。声誉不够,还需要7个,哈哈。我们必须回到它:)就是这样。我知道有一种方法,你也启发了我:D!我想我会采纳你的建议,合并猫表和标签表——我最初将它们合并为“术语”,是时候重新编码了,正如我所同意的,它最终会简化。谢谢。这就是为什么在这里;-)你可能想在接受我的答案的同时投票。声誉不够,还需要7个,哈哈。我们将不得不回到它:)