在编辑一些查询以添加没有值的列的备选方案时,我不小心写了类似这样的内容(这是简单的版本):
SELECT id, (SELECT name) FROM t
令我惊讶的是,MySQL没有抛出任何错误,但完成了查询,给出了我的预期结果(name
列值)。
我试图找到有关它的任何文档,但没有成功。
这是SQL标准还是MySQL专业?
我可以确定此语法的结果实际上是来自同一(外部)表的列值吗?扩展版本将是这样的:
SELECT id, (SELECT name FROM t AS t1 where t1.id=t2.id) FROM t AS t2
但EXPLAIN
报告了No tables used
列中Extra
的前一版本,我认为这非常好。
这是一个简单的fiddle on SqlFiddle(它为我保留时间,我希望你有更好的运气)。
澄清:我知道子查询,但我总是编写子查询(相关或不相关),暗示了一个表可供选择,因此在执行计划中引起了额外的步骤;我的问题是这个语法及其给出的结果,在MySQL中似乎没有任何返回预期的值。
答案 0 :(得分:3)
您在第一个查询中的内容是相关子查询,它只返回表 t 中的名称列。没有实际的子查询需要在这里运行(这是你的EXPLAIN告诉你的)。
在SQL数据库查询中,相关子查询(也称为 synchronized子查询)是一个子查询(嵌套在另一个子查询中的查询) 查询)使用外部查询中的值。
SELECT id, (SELECT name) FROM t
与
相同SELECT id, (SELECT t.name) FROM t
您的第二个查询
SELECT id, (SELECT name FROM t AS t1 where t1.id=t2.id) FROM t AS t2
还包含相关子查询,但这个实际上是在表t上运行查询以查找t1.id = t2.id的记录。
答案 1 :(得分:2)
这是SQL语言的默认行为,它在SQL ANSI 2011 over ISO/IEC 9075-1:2011(en)文档中定义。不幸的是它没有公开。 4.11 SQL语句一节中描述了此行为。
出现这种情况是因为数据库在没有from子句的情况下处理select命令,因此如果遇到:
select id, (select name) from some
它会尝试将name
字段作为要处理的外部查询的列。
幸运的是,我记得前一段时间我在这里有answered个人找到了一个有效的可用链接,这个链接指向一个在线完全在线的SQL ANSI文档,但它是针对SQL ANSI 99而且该部分可能是与新文件不一样。我认为,没有检查,它是在4.30节。看一看。我真的推荐阅读(我在当天做了那个)。
答案 2 :(得分:0)
它不标准。在oracle中,
select 1, (select 2)
from dual
引发错误ORA-00923: FROM keyword not found where expected
您如何确定结果?在编写查询之前,请更好地了解查询应该实现的内容。即使是问题中的解决版本也没有任何意义。