- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我继承了这个 MySQL 查询作为一些遗留代码:
SELECT
HardwareAddress, CONV(SUBSTRING(EventValue,3,2), 16, 10) AS 'Algorithm'
FROM ( SELECT @prev := '') init
JOIN
( SELECT HardwareAddress != @prev AS first,
@prev := HardwareAddress,
HardwareAddress, EventValue, ID
FROM Events
WHERE Time > {unixtime}
AND EventType = 104
AND HardwareAddress IN ({disps})
ORDER BY
HardwareAddress,
ID DESC
) x
WHERE first;
{unixtime}
和 {disps}
是用 Python String.format() 方法填充的变量。
我很难从这个查询中创建新功能,因为没有人了解它是如何工作的,而且我也找不到足够的文档。我所知道的是,该查询从 IoT 设备发送的长十六进制字符串中提取了一个名为“算法”的值列表。
subselect和interval变量的工作原理我大概明白了,但是还有很多不明白。 FROM (SELECT @prev := '') init
行如何工作?查询的最后两行也让我感到困惑。为什么子查询别名为 x
而没有任何内容引用它,WHERE first
到底是什么意思?
如果有人能够向我介绍这段代码的作用,我将不胜感激。
最佳答案
让我们将 SQL 分成几部分。整体的核心是 JOINed 子查询:
SELECT
HardwareAddress != @prev AS first,
@prev := HardwareAddress,
HardwareAddress,
EventValue,
ID
FROM Events
WHERE
Time > {unixtime}
AND EventType = 104
AND HardwareAddress IN ({disps})
ORDER BY HardwareAddress, ID DESC
第 1 列:(还)不知道 @prev
是什么,我们看到运算符是 !=
。这意味着无论其操作数是什么,第 1 列都将是一个二进制值。在 MySQL 中,1
或 0
。
第 2 列:将 SQL 变量 @prev
设置为当前匹配行的值。下面进行讨论,但就查询而言,结果将始终为 NULL
。
第 3、4、5 列:我假设不言自明。
限制条件 1、2、3:我假设不言自明。
ORDER BY:值得注意的是,查询按第 3 列 HardwareAddress
对结果进行排序,然后按 ID
降序。
然后第一列是一个 bool 值,表示此行的 HardwareAddress
列是否与上一行的相同。在上下文中,1 表示这是 HardwareAddress
的第一行,给定 ORDER BY
。
因此,查询将返回如下结果:
+-------+--------------------------+-------------------+------------+-----+
| first | @prev := HardwareAddress | HardwareAddress | EventValue | ID |
+-------+--------------------------+-------------------+------------+-----+
| 1 | NULL | ff:ff:9d:5f:f5:01 | ... | 10 |
| 0 | NULL | ff:ff:9d:5f:f5:01 | ... | 9 |
| 0 | NULL | ff:ff:9d:5f:f5:01 | ... | 8 |
| 0 | NULL | ff:ff:9d:5f:f5:01 | ... | 7 |
| 1 | NULL | ff:ff:9d:5f:f5:02 | ... | 200 |
| 0 | NULL | ff:ff:9d:5f:f5:02 | ... | 37 |
| 0 | NULL | ff:ff:9d:5f:f5:02 | ... | 24 |
| 0 | NULL | ff:ff:9d:5f:f5:02 | ... | 23 |
| 0 | NULL | ff:ff:9d:5f:f5:02 | ... | 22 |
| 1 | NULL | ff:ff:9d:5f:f5:03 | ... | 152 |
| ... | NULL | ff:ff:9d:..:..:.. | ... | ... |
| ... | NULL | ff:ff:9d:..:..:.. | ... | ... |
| ... | NULL | ff:ff:9d:..:..:.. | ... | ... |
+-----+----------------------------+-------------------+------------+-----+
将其与外部查询的约束放在一起,WHERE first
,最终结果为:
+-------+--------------------------+-------------------+------------+-----+
| first | @prev := HardwareAddress | HardwareAddress | EventValue | ID |
+-------+--------------------------+-------------------+------------+-----+
| 1 | NULL | ff:ff:9d:5f:f5:01 | ... | 10 |
| 1 | NULL | ff:ff:9d:5f:f5:02 | ... | 200 |
| 1 | NULL | ff:ff:9d:5f:f5:03 | ... | 152 |
+-----+----------------------------+-------------------+------------+-----+
换句话说,整个查询尝试获取给定顺序中每个 HardwareAddress 的第一个。神奇的 FROM (SELECT @prev := '') init
?这只是初始化 SQL 变量 @prev
以便在随后的子查询中使用。尾部 ... ID DESC) x
部分将内部查询别名为 x
。人们可能会利用这些别名进一步连接更复杂的查询,但在这种情况下,它们是出于 MySQL 语法原因。您可以忽略它们。
总而言之,这是一种获取与每个 HardwareAddress 关联的最大 ID 的非常低效的方法。如果查询需要每列的最大值,那么直接用MAX询问即可。考虑:
SELECT
HardwareAddress,
CONV(SUBSTRING(EventValue,3,2), 16, 10) AS 'Algorithm',
MAX(ID) AS ID
FROM Events
WHERE
Time > {unixtime}
AND EventType = 104
AND HardwareAddress IN ({disps})
GROUP BY 1, 2;
您的输出中将有一个额外的 ID;如果代码太脆弱而无法处理新列,您可以类似地将其屏蔽掉,就像原始查询对子选择所做的那样:
SELECT HardwareAddress, CONV(...) AS 'Algorithm'
FROM (SELECT ...) x
尽管 AND EventType
和 AND HardwareAddress
的选择性如何,这应该是一个更有效的查询。如果 ID
列有索引就更好了。
关于MySQL 区间变量和子查询符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49018471/
我在 Python 中使用 matplotlib,并制作了一个带条形的直方图。现在,当直方图出现时,仅 5 的倍数出现在 x 轴上,1000 的倍数出现在 y 轴上。对于 y 轴,这完全没有问题,但对
我正在使用 JavaScript 和 jQuery。我有以下脚本每 30 秒提醒一次 hi。 $(document).ready( function() { alert("hi"); setI
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
在 Numpy(python 包)中,可以使用语法 numpy.linspace(minValue, MaxValue, numberOfSamples) 构造 float 的离散区间。 . 我看到
所以我想在 -3 到 3 的区间内制作一些数字,以便在下面绘制这些函数,所以我想要尽可能多的数字。 我这样做: double k[601]; double y[601]; for (int i = 0
我有一个 Postgresql 表,用于存储有关计划进程的信息,包括上次执行进程的时间。不同的进程对其运行频率有不同的要求。 我列出了需要重新运行的进程列表: SELECT * FROM proces
如何正确使用此类带日期间隔的查询 @SqlUpdate("delete fromlogin where created < now() - ':days days' :: interval") v
我正在尝试计算图中的间隔,我在维基百科上找到了算法的数学描述: http://en.wikipedia.org/wiki/Interval_(graph_theory) H = { n0 }
我有一个基于 Informix-SQL 的 Pawnshop 应用程序,该应用程序根据黄金的重量和纯度计算应向客户贷出多少钱。当铺的最低贷款额为 5.00 美元。当铺员工通常会借出以 5 或 0 结尾
我将 NHibernate 与代码映射一起使用,并且我有一个由此公式创建的属性。 Property(x => x.IsInOverdue, mapper => mapper .Fo
我正在尝试从头开始为 Beta 分布编写卡方拟合优度检验,而不使用任何外部函数。下面的代码报告“1”适合,即使来自 scipy.stats 的 kstest 返回零。数据是正常分布的,所以我的函数也应
如何在 C# 中将任何值四舍五入到 10 区间?例如,如果我有 11,我希望它返回 10,如果我有 136,那么我希望它返回 140。 我可以很容易地用手做 return ((int)(number
如何在 Go 中表示 PostgreSQL 区间? 我的结构看起来像这样: type Product struct { Id int Name
我想编写一个函数,将数值限制在封闭的 0,1 区间内: func clamp01(_ value:T) -> T { return value 1 ? 1 : value } 在 Swift 3
我有一个简单的表格,用于存储来自在线仪表的降水读数。这是表定义: CREATE TABLE public.precip ( gauge_id smallint,
a = y def __gt__(self, y): return not self.x > y def __eq__(self, y): return
我正在处理 pandas 数据框 D=pd.DataFrame(data=[1.0,2.0,2.0,2.0,5.0,3.0,2.0,2.0,5.0,5.0,8.0,1.0]) 我识别低于特定阈值的值
我编写了一些C++代码来解决此问题: #include #include using namespace std; unsigned int countSetBits(unsigned int n
好的,我知道之前有人用一个有限的缩放示例问过这个问题 [-1, 1]间隔 [a, b] Different intervals for Gauss-Legendre quadrature in num
我是一名优秀的程序员,十分优秀!