我可以重写这个 SQL 查询以避免“ORDER BY 子句无效”吗
Posted
技术标签:
【中文标题】我可以重写这个 SQL 查询以避免“ORDER BY 子句无效”吗【英文标题】:Can I rewrite this SQL query to avoid the "The ORDER BY clause is invalid " 【发布时间】:2020-06-19 02:48:41 【问题描述】:我最初的查询是这样的:
select a.ID, a.TransactionID, b.Result
from MyDB.Result a inner join MyDB.ResultData b on a.ID=b.ID
where a.ID < 100000 and a.CreatedOn > '2020-01-01'
order by a.ID
但我在 Elasticsearch JDBC 输入中遇到错误
ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP、OFFSET 或 FOR XML。
为了解决这个问题,我将其重构为:
select TOP 500 a.ID, a.TransactionID, b.Result
from MyDB.Result a inner join MyDB.ResultData b on a.ID=b.ID
where a.ID < 100000 and a.CreatedOn > '2020-01-01'
order by a.ID
有什么方法可以重写它,这样就不必要求 TOP 500 而是让 JDBC 插件使用其内置设置?
编辑: 这是日志中的一部分。这看起来确实是作为更大查询的一部分运行的。
(1.251403s) SELECT TOP (1) count(*) AS [COUNT] FROM (select TOP 500 a.ID, a.TransactionID, b.Result from MyDB.Result a inner join MyDB.ResultData b on a.ID=b.ResultID where a.ID < 100000 and a.CreatedOn > '2020-01-01' order by a.ID) AS [T1]
(8.845048s) SELECT * FROM (select TOP 500 a.ID, a.TransactionID, b.Result from MyDB.Result a inner join MyDB.ResultData b on a.ID=b.ResultID where a.ID < 100000 and a.CreatedOn > '2020-01-01' order by a.ID) AS [T1] ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 500 ROWS ONLY
【问题讨论】:
原始查询没有问题。这还嵌入了什么?如果是较大的查询,则它必须是一部分,如果是,则 order by 必须在外部查询中。顺便说一句,虽然 TOP 会停止错误,但它实际上是在说“按 ID 排序时返回前 500 行”,如果它在子查询等中,它不会对结果进行排序。 你哪里有这个SQL语句。请把整个代码,你是如何在 JDBC 中调用的 根据错误,他的 ORDER BY 子句在视图中无效....,这不是您的原始错误。您可以在最终查询中编写 ORDER BY。 @VenkataramanR 这是我提供给 Logstash 输入插件以获取数据的语句。它不是代码的一部分。只是脚本的一部分。 @TomC 我从日志中添加了一些部分。不得不编辑一些东西,但我认为应该没问题。 【参考方案1】:当您使用带有 TOP 子句作为 FROM 的子查询时,它需要 ORDER BY。
子查询规则
只有在同时指定了 TOP 时才能指定 ORDER BY。
Read about all subquery rules
您可以做的是,您可以将 ORDER BY 移到 FROM 子句之外。我知道您想要所有行,而不是只有 500 行。
(1.251403s) SELECT TOP (1) count(*) AS [COUNT] FROM (select a.ID,
a.TransactionID, b.Result from MyDB.Result a inner join MyDB.ResultData b
on a.ID=b.ResultID where a.ID < 100000 and a.CreatedOn > '2020-01-01') AS [T1]
order by ID
(8.845048s) SELECT * FROM (select a.ID, a.TransactionID, b.Result from MyDB.Result a
inner join MyDB.ResultData b on a.ID=b.ResultID where a.ID < 100000
and a.CreatedOn > '2020-01-01' order by a.ID) AS [T1] ORDER BY ID
【讨论】:
我不认为 OP 可以做到这一点 - 他们似乎只是通过嵌入式查询。库的其他部分将其嵌入为子查询。 @TomC,OP 提到要绕过,我重构了查询。就是这个原因,我提过以上是关于我可以重写这个 SQL 查询以避免“ORDER BY 子句无效”吗的主要内容,如果未能解决你的问题,请参考以下文章
优化 SQL:如何重写此查询以提高性能? (使用子查询,摆脱 GROUP BY?)