MySQL:按日期接近分组?

标签 mysql sql group-by aggregate-functions

我写了这个查询,它几乎完成了我想要的:

SELECT * FROM 
(
   SELECT COUNT(*) as cnt,
   lat,
   lon,
   elev, 
   GROUP_CONCAT(CONCAT(usaf,'-',wban))
   FROM `ISH-HISTORY_HASPOS` 
   GROUP BY  lat,lon,elev 
 ) AS x WHERE cnt >=1;

输出:

+-----+--------+----------+--------+-------------------------------------------------+
| cnt | lat    | lon      | elev   | GROUP_CONCAT(CONCAT(usaf,'-',wban))                              |
+-----+--------+----------+--------+-------------------------------------------------+
|   4 | 30.478 |  -87.187 | 36     | 722220-13899,722221-13899,722223-13899,999999-13899              |
|   4 | 36.134 |  -80.222 | 295.7  | 723190-93807,723191-93807,723193-93807,999999-93807              |
|   5 | 37.087 |  -84.077 | 369.1  | 723290-03849,723291-03849,723293-03849,724243-03849,999999-03849 |
|   5 | 38.417 | -113.017 | 1534.1 | 745200-23176,745201-23176,999999-23176,724757-23176,724797-23176 |
|   4 | 40.217 |  -76.851 | 105.8  | 999999-14751,725110-14751,725111-14751,725118-14751              |
+-----+--------+----------+--------+-------------------------------------------------+

这将返回位于相同坐标的站点的串联列表。但是,我只对连接具有相邻日期范围的站点感兴趣。我从 (ISH-HISTORY_HASPOS) 中选择的表有两个日期时间列:“开始”和“结束”。我需要这两列的值彼此相差 3 天以内以满足 GROUP_CONCAT 条件。

编辑:为了让站点包含在最终结果的 GROUP_CONCAT 中,它必须满足以下条件:

  1. 它必须与列表中的另一个站位于同一位置(按 纬度、经度、高度)

  2. 它的end时间必须在另一个电台的begin时间的3天内或者它的begin时间必须在3天内另一个站的 结束时间。当我说“另一个站”时,我指的是站 位于同一地点(满足#1 的条件)。

我认为我将不得不使用子查询,但我似乎不知道如何去做。一些帮助将不胜感激!查询或存储过程都很好,但 php 解决方案也可以接受。

这是我正在查询的表的转储:sql dump

结果应该与我的示例相同,但不应该存在非相邻项(按日期)。

最佳答案

解决方案可能是使用子查询来计算彼此相隔 3 天内的站点列表,并将此子查询作为 where 子句添加到主查询中。 子查询包含一个笛卡尔乘积,用于列出所有可能的站对,第一个条件仅获取结果矩阵的前半部分,两个条件用于指定时间限制。至于后面这些条件我只是猜到了,我真的不知道 beginend 字段的度量单位。 结果查询可能是这样的:

SELECT * FROM (
    SELECT COUNT(*) AS
       cnt,
       lat,
       lon,
       elev,
    GROUP_CONCAT(CONCAT(usaf, '-', wban))  
    FROM ISH-HISTORY_HASPOS  
    WHERE id IN (
        SELECT DISTINCT t1.id  
        FROM ISH-HISTORY_HASPOS t1  
        INNER JOIN ISH-HISTORY_HASPOS t2
           ON t1.lon = t2.lon
           AND t1.lat = t2.lat
           AND t1.elev = t2.elev  
        WHERE t1.id < t2.id
            AND abs(t1.begin - t2.end) < 259200
            AND abs(t1.end - t2.begin) < 259200  
        UNION  
        SELECT DISTINCT t2.id  
        FROM ISH-HISTORY_HASPOS t1  
        INNER JOIN ISH-HISTORY_HASPOS t2
            ON t1.lon = t2.lon
            AND t1.lat = t2.lat
            AND t1.elev = t2.elev  
        WHERE t1.id < t2.id
            AND abs(t1.begin - t2.end) < 259200
            AND abs(t1.end - t2.begin) < 259200
    )
    GROUP BY lat, lon, elev   
) AS x WHERE cnt >= 1;

关于MySQL:按日期接近分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13675263/

相关文章:

mysql - 在选择查询中获取选定字段的替代方法

mysql - 如何在不直接访问数据库的情况下修改MySQL表结构?

sql - 跟踪 Microsoft SQL Server 数据库中的更改

r - 分组执行 ifelse 的更好方法

MySQL 双左连接、条件 OR 和组

c# - 按任意时间间隔对 DateTime 进行分组

mysql - 如何构造 ifists 查询以生成错误消息

php - 有没有一种方法可以在 MySQL 的一个查询中获取涉及连接到同一个表的 2 列的结果集?

sql - 运行命令行 SQLite 查询并退出

sql - 使用递增引用更新 postgresql 表列