第二次从内部查询中选择

Posted

技术标签:

【中文标题】第二次从内部查询中选择【英文标题】:Selecting from an inner query a second time 【发布时间】:2019-05-05 14:17:50 【问题描述】:

在练习编写 SQL 查询时,我注意到我无法以类似于以下的形式执行查询:

(1)

SELECT attr1, attr2 FROM
   (SELECT attr1, attr2 FROM ...) AS table     
WHERE attr1 >= ALL
   (SELECT attr1 FROM table)

(1) 中的想法是我从别名为“表”的内部查询中进行选择。我还想添加一个 WHERE 子句来应用比较并获得我想要的查询结果。所以我将属性与“表”中的属性进行比较。

在这种特定情况下,我选择了所有在分配了别名“表”的内部查询结果中获得最大值的 attr1。

但是上面的例子不起作用,我得到一个错误。

我意识到如果我执行以下操作,我将获得查询结果:

(2)

SELECT attr1, attr2 FROM
   (SELECT attr1, attr2 FROM ...) AS alias1   
WHERE attr1 >= ALL
   (SELECT attr1 FROM ...)

两个内部查询是相同的,除了 attr2 在第二个查询中不存在。

我对查询 (2) 的唯一问题是,如果内部查询很长,那么您实际上是在复制和粘贴一大块代码,以便在 WHERE 子句下再次重用。

我的问题是为什么查询 (1) 无效,以及查询 (2) 是否有更好的替代方案。

【问题讨论】:

如果WHERE 应该适用于内部查询,则尝试将其添加到内部而不是外部查询。 您的第二个查询没有意义。 where 子句中有一个别名。示例数据、期望的结果以及您想要实现的逻辑的解释都非常有用。 这是我的错误,我并不是要在where 子句中放置别名。现在会修复它 【参考方案1】:

如果你只想要一行,那么你可以使用ORDER BYLIMIT

SELECT attr1, attr2
FROM (SELECT attr1, attr2 FROM ...) t
ORDER BY attr1 DESC
LIMIT 1;

如果您使用的是 mysql 8+,则可以使用 RANK() 获取重复项:

SELECT attr1, attr2
FROM (SELECT attr1, attr2,
             RANK() OVER (ORDER BY attr1 DESC) as seqnum
      FROM ...
     ) t
WHERE seqnum = 1;

在早期版本中,您要么需要重复子查询,要么需要使用变量。

【讨论】:

【参考方案2】:

查询 1 无效,因为 SELECT 子句和列使用在 FROM 和 WHERE 子句之后执行的子查询 a 动态构建

因此在您执行 select 时该表不可用。

第二个,对于 where 列中存在别名应该是无效的,这是 this 的一部分

   SELECT attr1, attr2 
FROM
   (SELECT attr1, attr2 FROM ...) AS alias1   
WHERE attr1 >= ALL
   (SELECT attr1 FROM ...) 

有效,因为子查询select子句中没有别名

但是查看您的代码,您应该评估 if 而不是 suqbery for select 和 where 条件,您可以将查询重构为连接查询

SELECT attr1, attr2 
FROM your_table 
(
  SELECT attr1, attr2 
  FROM your_table 
  WHERE  .... ) AS alias1   
WHERE alias1.attr1   >= your_table.att1

【讨论】:

以上是关于第二次从内部查询中选择的主要内容,如果未能解决你的问题,请参考以下文章

选择排序

java 选择排序与冒泡排序

排序:直接选择排序

直接选择排序

无法连续两次从列表框中选择相同的项目 - windows phone 8 C#

Java 选择排序