如何重写具有连接子查询的 SQL 查询

Posted

技术标签:

【中文标题】如何重写具有连接子查询的 SQL 查询【英文标题】:How to rewrite SQL query that has subquery with joins 【发布时间】:2011-09-22 17:32:53 【问题描述】:

我有一个 SQL 查询,它有一个包含连接的子查询。我想重写没有子查询的查询,以便我可以创建一个视图。 mysql 不允许 FROM 是子查询的 SELECT 语句。

这可能吗?我已经尝试删除外部选择并在 subs 查询中移动组。这部分有效,但某些数据不正确。

select *
from (SELECT r.id, r.dateAdded, r.listingId, r.rating, r.username, r.valid, tbl_data.nameShort, tbl_data.desk, d.model, d.hardware, d.serial, l.appVersion, r.photoUrl, r.comment
      FROM tbl_ratings r
      JOIN tbl_data on r.listingId = vi_data.id
      JOIN tbl_devices d on r.serial = d.serial
      JOIN tbl_log l on l.serial = d.serial
      ORDER BY d.serial, l.dateAdded DESC) x
group by id
order by dateAdded DESC

提前致谢!

【问题讨论】:

为什么不直接执行内部查询? 嗯,我从 tbl_ratings 获得了超过 7000 个结果,而不是 350+。如果没有 group by,我会得到一些重复的信息。 您打算执行“INNER JOIN”还是“LEFT JOIN”,但不小心得到了“OUTER JOIN”? 【参考方案1】:

是不是就这么简单:

SELECT     r.id, r.dateAdded, r.listingId, r.rating, r.username, r.valid,
           tbl_data.nameShort, tbl_data.desk, d.model, d.hardware,
           d.serial, l.appVersion, r.photoUrl, r.comment
      FROM tbl_ratings r
      JOIN tbl_data on r.listingId = vi_data.id
      JOIN tbl_devices d on r.serial = d.serial
      JOIN tbl_log l on l.serial = d.serial
      GROUP BY r.id
      ORDER BY r.dateAdded DESC

此外,您还有对“vi_data”的引用,该引用不在查询中的其他任何位置

【讨论】:

谢谢,vi_data 出错了。它应该是 tbl_data。这有效,但是应用程序版本不正确。它不显示最新的应用程序版本。用户可以运行不同版本的应用程序。在派生表中,我能够按 l.dateAdded 进行排序,这为我提供了最新的日志信息。 考虑添加类似“WHERE l.appVersion = xxx”的子句来限制appVersion... 感谢您的所有帮助。我现在可能只是跳过应用程序版本。每个人都不会总是拥有最新版本,因此我无法在查询中指定应用版本。 我按照您的建议重新进行了查询,并确保索引设置正确且一切正常——而且速度也很快。【参考方案2】:

将您的 group by 子句更改为 group by r.id。由于您从派生表(子查询)中进行选择,因此数据库无法判断该派生表中只有一个“id”字段 - 它只看到子查询中指定的列标题,即r.id .

【讨论】:

将 id 更改为 r.id 不会摆脱子查询。此外,它给了我一个错误“'group statement'中的未知列'r.id'” 您最好对所有字段进行别名处理,select r.id AS rid,然后您就可以在***查询中使用 x.rid。

以上是关于如何重写具有连接子查询的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

具有 group by 和两个表连接的 Sql 子查询

在 JOIN 中重写慢速 SQL(子)查询

帮助将子查询转换为带连接的查询

Oracle SQL:: 子查询中带有 orderby 的 Rownum 抛出缺少括号

有关优化此多层(具有多层子查询)SQL 查询的提示

sql子查询和连接查询的区别是啥呢?