当前位置: 首页 > 面试题库 >

使用用户变量对行进行编号时的保证

厍兴腾
2023-03-14
问题内容

我经常在SO上找到答案,建议使用用户变量对某些事物进行编号。也许最清楚的例子是从给定结果集中选择第二行的查询。(此问题和查询与此答案相似,但实际上是此答案触发了此问题)。

SELECT *
FROM (SELECT *, (@row := @row + 1) AS rownum
      FROM (SELECT @row := 0) AS init, tablename
      ORDER BY tablename.ordercol
     ) sub
WHERE rownum % 2 = 1

这种方法似乎确实可以正常工作。

注意的理由

另一方面,MySQ文档指出:

通常,永远不要为用户变量分配值,并且不要在同一条语句中读取该值。您可能会得到预期的结果,但这不能保证。涉及用户变量的表达式的求值顺序是不确定的,并且可能会根据给定语句中包含的元素而改变;此外,在MySQL服务器的发行版之间,不能保证此顺序相同。

核心问题

因此,我的问题不是不是如何使用当前服务器来实现这种排序,而是要 确保 使用用户变量的建议解决方案是否可以 保证
在所有(合理)情况下以及对于所有将来的MySQL版本都可以使用。

通过 鈥済鈥uarantees
我的意思是权威的来源,如MySQL文档或与一些标准的MySQL要求的一致性。缺乏这种权威性的答案,可能会引用其他资源,例如常用教程或MySQL源代码的一部分。通过
鈥渨兽人鈥 我的意思是分配会按顺序执行,每个结果行一次,并在由产生的顺序的事实ORDER BY一致。

中断查询的示例

举个例子,失败很容易发生:

SELECT *
FROM (SELECT *, (@row := @row + 1) AS rownum
      FROM (SELECT @row := 0) AS init, tablename
      HAVING rownum > 0
      ORDER BY tablename.ordercol
     ) sub
WHERE rownum % 2 = 1

在SQL Fiddle上当前安装的MySQL
5.5.27上将产生空结果。原因似乎是该HAVING条件导致rownum表达式两次被求值,所以最终结果将只有偶数。我对幕后发生的事情有一个了解,但我并没有断言带有的查询HAVING是很有意义的。我只想证明在有效的代码和看起来非常相似但会中断的代码之间有一条很好的界限。


问题答案:

您误读了该声明。使用多个变量时,它与SELECT列表中表达式的顺序有关。
如前所述,在此单变量语句上的ORDER BY具有保证的顺序,直到MySQL的当前版本为止,并且该文本中没有任何内容表明它将改变。

但是 保证未来 吗?谁知道。

关于 中断查询 ,您再次误解了MySQL的工作方式。让我们分解一下您的查询。注意手册中的这一声明

在SELECT语句中,每个选择表达式仅在发送到客户端时才进行求值。这意味着在HAVING,GROUP BY或ORDER
BY子句中,引用在选择表达式列表中分配了值的变量不能按预期工作

查询的处理顺序大致

FROM / JOIN
WHERE / ON
GROUP BY / ROLLUP
HAVING
UNION
SELECT
ORDER BY
@variable resolution

您的“中断”查询尝试在同一级别使用WITHIN变量,这与对列别名使用WHERE /
HAVING子句几乎一样有罪。这就是为什么您永远不会在同一查询级别上看到使用该变量的基于MySQL变量的row_numbering解决方案的原因,它始终在子查询中。外部查询可以视为client内部查询的内部查询,在该阶段已呈现变量/占位符表达式。根据您的论点,您可以使用直接涉及@row的WHERE子句轻松地将其破坏(是的,
它将 运行!)。



 类似资料:
  • 是否可以使用非类型变量模板进行运行时计算? 想象一下以下情况: 方法应该返回给定整数在模板参数包中的位置。如果参数包中不存在给定的整数,则应生成错误(最好是在编译时)。 另外,我知道如果签名改为 不幸的是,这不是我的选择,因为方法应该是虚拟的。

  • 问题内容: 在过去的两年中,我一直在编写Java,现在,我开始用python(另外)进行编写。 问题是,当我查看我的Python代码时,似乎有人试图将Java代码转换为python格式,但结果却很糟糕,因为- python不是Java。 关于如何摆脱“用Python编写Java”模式的任何技巧? 谢谢! 问题答案: 您可能会考虑将自己沉浸在Python范例中。最好的方法是首先了解他们的知识,然后通

  • 问题内容: 我有一个 变量字符串 ,其中包含格式正确且有效的XML。我需要使用JavaScript代码来解析此供稿。 如何使用(浏览器兼容)JavaScript代码来完成此操作? 问题答案: Internet Explorer和基于Mozilla的浏览器为XML解析提供了不同的对象,因此明智的是使用jQuery之类的JavaScript框架来处理跨浏览器的差异。 一个非常基本的例子是: 注:如评论

  • 我想把一个spring boot环境变量的值放入一个验证注释(@min,@max),但我不知道怎么做。下面是我的代码: 这是我的application.yml: 我想把我的yml的字段“min”和“max”放入我的属性uitype的注释字段@min()和@max()中。有人知道怎么做吗?提前感谢您的帮助!

  • 我在服务器端对JSON进行了编码(使用ESAPI编码器),然后客户机检索bean的字段并进行进一步的处理。 在服务器端 编码的JSON字符串 \x7b\x22name\x22\x3a\x22sameer\x22,\x22company\x22\x3a\x22company\x22,\x22designation\x22\x3a\x22developer\x22\x7d 在客户端

  • 本文向大家介绍使用base64对图片的二进制进行编码并用ajax进行显示,包括了使用base64对图片的二进制进行编码并用ajax进行显示的使用技巧和注意事项,需要的朋友参考一下 使用base64对图片的二进制进行编码并用ajax进行显示 有时候我们需要动态的将图片的二进制在页面上进行显示,如我们需要弄一个验证码的功能,那么如果我们的验证码的图片在后台得到的是该图片的二进制,那么当我们需要在页面上