【发布时间】:2018-02-15 03:16:35
【问题描述】:
我的问题可能类似于这些问题:
- MySQL group by with ordering/priority of another column
- Grouping by Column with Dependence on another Column
- MySQL GROUP BY with preference
表格示例:
source zip phone street city created_at
==================================================================
a 11111 11111 Flatlands null 2015-01-01
b 11111 11111 Flatlands Avenue New York 2015-01-01
c 11111 11111 Ave Flatlands New York 2015-01-01
a 22222 22222 Favory New York 2015-01-01
b 22222 22222 Favory Avenue New York 2017-12-12
c 22222 22222 Ave Favory New York 2015-01-01
b 33333 33333 Sixteenth Washington 2015-01-01
c 33333 33333 st. 16th null 2015-01-01
c 44444 44444 st. West Land null 2015-01-01
假设我有一张表格,其中包含有关不同城市地点的信息。这些信息来自 3 个不同的来源:a、b 和 c。
zip 和 phone 字段唯一标识位置,因此数据库中的行可以按这些字段分组。
我需要合并来自不同来源的不同位置的信息,根据street 和city 列的规则集选择最佳值。
规则是:
- 对于每个组,将
street和city的非空值优先于空值。 - 在每个组中,
street和city列的值从a和b源优先于c源(权重(a)= 权重(b)> 权重(@987654344 @)) 如果这些列不为空。 - 对于源
a和b,优先考虑具有最新created_at时间戳的行中的列值。
这是我想要收到的结果:
zip phone street city
====================================
11111 11111 Flatlands New York
22222 22222 Favory Avenue New York
33333 33333 Sixteenth Washington
44444 44444 st. West Land null
Here is a DB Fiddle to play with.
我不确定这是否可以通过 SQL 实现,也许我最好的选择是切换到 NoSQL DB + 命令式处理任务。或者只是使用一些工具从数据库中提取信息,然后对其进行处理。
附:这是一个简化的例子。
【问题讨论】:
-
第一个和第二个条件可以在
GROUP BY查询中验证,但第三个条件不能。您不能使用GROUP BY选择行。GROUP BY使用来自每个组的数据计算新行。您不能使用GROUP BY选择行。GROUP BY使用来自每个组的数据计算新行。在similar (but much simpler) question 上查看this answer。 -
每次我需要从表中获取值时,我都不会编写一个怪物查询(有或没有
GROUP BY)来运行。我会将其视为草稿表,并创建另一个表来为每一对(zip、phone)存储一行,并使用您需要的任何标准来管理其他字段。需要数据的脚本将从“干净”表中读取;另一个脚本将使用“草稿”表来计算“干净”记录。这可以定期运行(并处理所有行)或仅在将新行添加到“草稿”时运行(并仅重新计算受影响的“干净”记录)。 -
在另一个 DBMS 中,您只需使用带有适当分区和排序顺序的
ROW_NUMBER来对记录进行排序。由于 MySQL 缺少ROW_NUMBER,请查看如何在 MySQL 中使用变量模拟ROW_NUMBER。
标签: mysql sql group-by sql-order-by