在 postgreSQL 中使用 WHERE 子句创建三个表的最有效方法是啥

Posted

技术标签:

【中文标题】在 postgreSQL 中使用 WHERE 子句创建三个表的最有效方法是啥【英文标题】:What the most efficient way to make a three tables JOIN with a WHERE clause in postgreSQL在 postgreSQL 中使用 WHERE 子句创建三个表的最有效方法是什么 【发布时间】:2015-04-04 11:04:54 【问题描述】:

我正在使用 postgreSQL 9.3。

我想说我的问题有点主观,但我没有找到任何相关的问题或文章......

我有如下三个表:

艺术家:

+--------+----------+
|artistId|   name   |
+--------+----------+
| 1      | James    |
| 2      | Jack     |
| 3      | Henry    |
| 4      | Tom      |
+--------+----------+

流派:

+---------+-----------+
| genreId |    name   |
+---------+-----------+
|   1     |   rock    |
|   2     |   dub     |
+---------+-----------+

和联结表艺术家流派:

+--------+---------+
|artistId| genreId |
+--------+---------+
|      1 |     1   |
|      2 |     2   |
|      3 |     1   |
|      4 |     2   |
+--------+---------+

我想按流派名称获取所有艺术家。 目前我是这样做的:

SELECT a.*
FROM artistsGenres aG
  INNER JOIN artists a ON a.artistId = aG.artistId
WHERE aG.genreId = (SELECT genreId FROM genres WHERE name = 'dub');

我想知道是否有更有效的方法来做到这一点?

【问题讨论】:

看起来您的查询不正确,您正在将 aG.artitsId 与genres.genreId 进行匹配。 你说得对,我编辑了我的问题。 一个艺术家可以有多个流派吗? (例如,artistgenres 行是否存在 artistId=1,genreId=2 ?) @wildplasser ,是的,它可以拥有。 【参考方案1】:

如果可以通过连接完成,一般最好不要使用子查询。然而幸运的是,查询规划器会为您重写子查询作为连接!如果你自己做的话,它会是这样的。

SELECT a.*
FROM artistsGenres aG
  INNER JOIN artists a ON a.artistId = aG.artistId
  INNER JOIN genres g ON g.genreId=aG.genreId
WHERE g.name='dub'

您执行连接的顺序并不重要,因为 postgresql 会将它们重新排序为它认为最有效的顺序。

【讨论】:

【参考方案2】:
SELECT *
FROM artists a
WHERE EXISTS (
  SELECT 1
  FROM artistsGenres aG
  JOIN genres g ON g.genreId = aG.genreId
  WHERE aG.artistId = a.artistId 
  AND g.name = 'dub'
  );

【讨论】:

感谢您的回答,但是您的查询似乎比Eelke的查询慢了一点(但是我的测试表很小,可能是这个原因)。 对于非平凡的情况,它只能更快。请注意,查询将产生不同的结果:在每个艺术家不止一个流派的情况下(这也需要选择以允许多个选择,例如在 AND g.name IN( 'country', 'dub') 中,@Eelke 的查询将为每个艺术家产生多个结果行,为每位艺术家挖掘一(或零)行。 考虑添加几行简短的解释,说明为什么这是最好的(以及在什么情况下)。指向良好参考的链接也会有所帮助。 @wildplasser:Eelke 的查询如何为每个艺术家生成多个结果行(因为一个艺术家可以有多个流派但不能有多个相同流派)?

以上是关于在 postgreSQL 中使用 WHERE 子句创建三个表的最有效方法是啥的主要内容,如果未能解决你的问题,请参考以下文章

Postgresql 包含在 where 子句中

PostgreSQL WHERE 子句

PostgreSQL WHERE 子句

postgresql 在 where 子句中使用 json 子元素

如何在 Ruby 中使用 Where 子句 (PostgreSQL) 中的变量编写查询

Drupal 8 和 PostgreSQL:如何在 WHERE 子句中使用表达式的结果?