如何在内部连接中使用in()子句?

06odsfpq  于 2021-06-20  发布在  Mysql
关注(0)|答案(3)|浏览(305)

我的问题是:

SELECT p.*
FROM posts p
INNER JOIN pivot pi on p.id = pi.post_id
INNER JOIN tags t on t.id = pi.tag_id and t.name = "mysql"

我所要做的就是获取带有特定标签的帖子。在上面的查询中,我用 mysql 标签。
现在我需要让它为多个标签工作。我的意思是,我想选择所有贴有这两个标签的帖子 mysql 以及 php . 我想我得用 IN() 查询中的子句。但我不知道具体是怎么回事。你知道吗?
例:这是我的table:

// posts
+----+---------+------------+
| id | subject |    body    |
+----+---------+------------+
| 1  | sub1    | content1   |
| 2  | sub2    | content2   |
+----+---------+------------+

// tags
+----+--------+
| id |  name  |
+----+--------+
| 1  | mysql  |
| 2  | php    |
+----+--------+

// pivot 
+---------+--------+
| post_id | tag_id |
+---------+--------+
| 1       | 1      |
| 2       | 1      |
| 2       | 2      |
+---------+--------+

的预期结果 [mysql] :

| 1  | sub1    | content1   |
| 2  | sub2    | content2   |

的预期结果 [mysql][php] :

| 2  | sub2    | content2   |
3bygqnnd

3bygqnnd1#

我会用一个 WHERE 条款,然后加总:

SELECT p.*
FROM posts p INNER JOIN
     pivot pi 
     ON p.id = pi.post_id INNER JOIN
     tags t 
     ON t.id = pi.tag_id 
WHERE t.name IN ('mysql', 'php')
GROUP BY p.id
HAVING COUNT(*) = 2;  -- this is the number of tags in the list

这假设标记没有重复。
关于使用 GROUP BY p.idSELECT p.* . 这实际上是有效的,并且是ansi标准允许的,假设 p.id 是独一无二的 posts . 具体规则基于函数依赖关系。
我确实认为mysql的最新版本默认情况下不允许这种构造。你总是可以这样做:

SELECT p.*
FROM posts p JOIN
     (SELECT pi.post_id
      FROM pivot pi INNER JOIN
           tags t 
           ON t.id = pi.tag_id 
      WHERE t.name IN ('mysql', 'php')
      GROUP BY p.id
      HAVING COUNT(*) = 2  -- this is the number of tags in the list
     ) t
     ON p.id = t.post_id ;
balp4ylt

balp4ylt2#

我不知道我们为什么要把事情复杂化。。
instade of in子句只需使用字符串输入进行查询,并将其与字符串聚合进行比较。

SELECT *
FROM posts P
INNER JOIN (
   SELECT post_id, CONCAT ("(", Group_concat(t.name SEPARATOR ' ,'), ")") AS tgs
   FROM pivote p
   INNER JOIN tag t
   ON (t.id = p.tag_id)
   GROUP BY post_id
   ) AA
 ON P.id = post_id
 WHERE tgs LIKE "(mysql,php)
vojdkbi0

vojdkbi03#

我想选择所有的职位都与mysql和php标记。我想我必须在查询中使用in()子句。
不。这将显示你的职位是标记一个或另一个。为了找到两者都有的帖子,我会两次加入到表中:

SELECT p.*
FROM posts p
INNER JOIN pivot pi1 on p.id = pi1.post_id
INNER JOIN tags t1 on t1.id = pi1.tag_id and t1.name = "mysql"
INNER JOIN pivot pi2 on p.id = pi2.post_id
INNER JOIN tags t2 on t2.id = pi2.tag_id and t2.name = "php"

...

相关问题