我写了这个查询,它几乎完成了我想要的:
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 中,它必须满足以下条件:
它必须与列表中的另一个站位于同一位置(按 纬度、经度、高度)
它的
end
时间必须在另一个电台的begin
时间的3天内或者它的begin
时间必须在3天内另一个站的结束
时间。当我说“另一个站”时,我指的是站 位于同一地点(满足#1 的条件)。
我认为我将不得不使用子查询,但我似乎不知道如何去做。一些帮助将不胜感激!查询或存储过程都很好,但 php 解决方案也可以接受。
这是我正在查询的表的转储:sql dump
结果应该与我的示例相同,但不应该存在非相邻项(按日期)。
最佳答案
解决方案可能是使用子查询来计算彼此相隔 3 天内的站点列表,并将此子查询作为 where 子句添加到主查询中。
子查询包含一个笛卡尔乘积,用于列出所有可能的站对,第一个条件仅获取结果矩阵的前半部分,两个条件用于指定时间限制。至于后面这些条件我只是猜到了,我真的不知道 begin
和 end
字段的度量单位。
结果查询可能是这样的:
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/