python - 如何在整个子查询中使用 group_concat?
问题描述
...无需进行不必要的比较
我想获得一系列行的 md5 哈希。由于带宽限制,我希望它发生在服务器端。
这有效:
create table some_table (id int auto_increment,
col1 varchar(1),
col2 int,
primary key (id));
insert into some_table (col1, col2)
values ('a', 1),
('b', 11),
('c', 12),
('d', 25),
('e', 50);
select group_concat(id,col1,col2) from
(select * from some_table
where id >= 2 and id < 5
order by id desc) as some_table
group by 1 = 1;
输出:
+----------------------------+
| group_concat(id,col1,col2) |
+----------------------------+
| 2b11,3c12,4d25 |
+----------------------------+
并使用哈希:
select md5(group_concat(id,col1,col2)) from
(select * from some_table
where id >= 2 and id < 5
order by id desc) as some_table
group by 1 = 1;
输出:
+----------------------------------+
| md5(group_concat(id,col1,col2)) |
+----------------------------------+
| 32c1f1dd34d3ebd33ca7d95f3411888e |
+----------------------------------+
但我觉得应该有更好的方法。
特别是,我想避免将 1 与 1 百万次进行比较,这是我发现将行范围放入一个组所必需的,我需要它才能使用group_concat
,我需要它才能md5
在多行上使用。
有没有一种方法可以group_concat
在行范围内使用(或类似的),而无需进行不必要的比较?
编辑
我想对多行进行哈希处理,以便可以比较不同服务器上生成的哈希值。如果它们不同,我可以得出结论,子查询返回的行存在差异。
解决方案
解决方案就是完全省略group by 1 = 1
。我曾假设这group_concat
需要我为其提供一个组,但它可以直接用于子查询,如下所示:
select group_concat(id,col1,col2) from
(select * from some_table
where id >= 2 and id < 5
order by id desc) as some_table;
请注意,空值需要转换为对 concat 友好的值,如下所示:
insert into some_table (col1, col2)
values ('a', 1),
('b', 11),
('c', NULL),
('d', 25),
('e', 50);
select group_concat(id, col1, col2) from
(select id, col1, ifnull(col2, 'NULL') as col2
from some_table
where id >= 2 and id < 5
order by id desc) as some_table;
输出:
+------------------------------+
| group_concat(id, col1, col2) |
+------------------------------+
| 2b11,3cNULL,4d25 |
+------------------------------+
group_concat
另一个警告:mysql 有一个由变量定义的最大长度: group_concat_max_len
. 为了散列n表行的串联,我需要:
- 散列行,使其以 32 位表示,无论它有多少列
- 确保
group_concat_max_len > (n * 33)
(额外的字节用于添加逗号) - 散列
group_concat
散列的行。
最终,我最终使用客户端语言来检查每列的名称、编号和可空性,然后构建如下查询:
select md5(group_concat(row_fingerprint)) from
(select concat(id, col1, ifnull(col2, 'null')) as row_fingerprint
from some_table
where id >= 2 and id < 5
order by id desc) as foo;
有关更多详细信息,您可以在此处查看我的代码(请参阅函数:find_diff_intervals)。
推荐阅读
- reactjs - 用于设置值的条件运算符不同步工作?
- java - 以编程方式屏蔽 RecyclerView 中的图像
- powershell - 如何在 PowerShell 脚本中加密/隐藏 ClearText 密码
- laravel - 如何在 HTML 视图中使用 .env.example 常量?
- javascript - 匹配正则表达式中的所有数字,除了短语 foo2020
- networking - 使用 Prometheus 和 Grafana 的网络传输速度(以 MB/s 为单位)
- wcf - 微软 grpc-for-wcf-developers-master 代码在 IIS 上失败
- lisp - 是否可以将二维数组作为 CLisp 中映射的结果类型?
- c# - 多次调用其方法时,C#如何处理内存中的变量?
- html - 如何在 tr 中使用在 html 中具有类的 CSS?