我们有一个获取GPS坐标数据的程序。我们可以根据数据库中的区域id获取数据集,如下所示:
gps_coords | year | value
105 | 2010 | 5.63
102 | 1990 | 3.2
103 | 2000 | 13.23
...
现在,我们希望将该查询集与另一个查询集结合使用,例如a.value + b.value
或(a.value+50)*b.value/100
这样的sql。我们还按度量过滤我们的查询(他们想要查询的数据集)。
问题是如何将两个gps_coords检索为一列。我想我们必须在同一张桌子上做JOIN
,但我不知道如何在同一列中同时获得a.gps_coords和b.gps_coords。
我的查询(如下)在100毫秒内执行零行。所以,我不确定出了什么问题。有谁知道如何在同一列中同时获得a和b的gps_coords?我正在使用Postgresql,但任何事情都会有所帮助。谢谢!
数据:
gps_coords
year
value
metric
区域:
gps_coords
region_id
数据
| gps_coords | year | value | metric |
| 506 | 2010 | 23.23 | 5 |
| 507 | 2010 | 10.32 | 5 |
| 508 | 2010 | 28.5 | 5 |
| 509 | 2010 | 45.24 | 5 |
| 506 | 2010 | 213.53 | 4 |
| 507 | 2010 | 0 | 4 |
| 508 | 2010 | 434.4 | 4 |
| 509 | 2010 | 381.1 | 4 |
地区
| gps_coords | region_id |
| 506 | 1 |
| 506 | 2 |
| 506 | 3 |
| 507 | 1 |
| 508 | 1 |
| 508 | 3 |
| 509 | 1 |
| 509 | 2 |
假设我想要区域1中的度量5的坐标,在区域3中添加度量4(在gps_coords 506上重叠),我想返回所有gps_coords(无论区域),然后指定值(添加到哪里)他们相交了):
| gps_coords | year | value |
| 506 | 2010 | 233.76 |
| 507 | 2010 | 0 |
| 508 | 2010 | 434.4 |
| 509 | 2010 | 45.24 |
SELECT DISTINCT init.gps_coords, init.year, a.value + b.value as value
FROM data as init
INNER JOIN data as a USING (metric, value)
INNER JOIN data as b USING (metric, value)
INNER JOIN regions as r
ON (init.gps_coords = r.gps_coords)
AND r.region_id = 1
INNER JOIN regions as ra
ON (a.gps_coords = ra.gps_coords)
AND ra.region_id = 2
INNER JOIN regions as rb
ON (init.gps_coords = rb.gps_coords)
AND rb.region_id = 3
WHERE a.metric = 5
AND b.metric = 4
ORDER BY init.gps_coords
上面是所有坐标,对于每个区域(区域1),然后是它们相交的地方添加的值(ra.region 2将包括coords 506和509,并且将添加rb.region 3的坐标:506和508 ,加入coords 506)。 507没有出现在任何一个区域id中,因此它是0或null,无论哪个。
答案 0 :(得分:1)
如果理解正确(我不确定),您的查询可能看起来像
SELECT COALESCE(b.gps_coords, c.gps_coords) AS gps_coords,
COALESCE(b.year, c.year) AS year,
COALESCE(b.value, 0) + COALESCE(c.value, 0) AS value
FROM
(
SELECT d.gps_coords, d.year, SUM(d.value) AS value
FROM data d JOIN regions r
ON d.gps_coords = r.gps_coords
WHERE d.metric = 5 AND r.region_id = 1
GROUP BY d.gps_coords, d.year
) b FULL JOIN
(
SELECT d.gps_coords, d.year, SUM(d.value) AS value
FROM data d JOIN regions r
ON d.gps_coords = r.gps_coords
WHERE (d.metric = 4 AND r.region_id = 3)
GROUP BY d.gps_coords, d.year
) c
ON b.gps_coords = c.gps_coords
AND b.year = c.year
ORDER BY gps_coords
示例输出:
| GPS_COORDS | YEAR | VALUE | -------------|------|--------| | 506 | 2010 | 236.76 | | 507 | 2010 | 10.32 | | 508 | 2010 | 462.9 | | 509 | 2010 | 45.24 |
这是 SQLFiddle 演示
答案 1 :(得分:0)
这个SQL完全符合我的需要:
SELECT a.gps_coords,
a.year,
COALESCE(AVG(b.v1), 0) + COALESCE(AVG(b.v2), 0)
FROM data a
LEFT JOIN (
SELECT d.gps_coords, d.year, d.value as v1, NULL v2
FROM data d JOIN regions r
ON d.gps_coords = r.gps_coords
WHERE d.metric = 4 AND r.region_id = 3
UNION
SELECT d.gps_coords, d.year, NULL, d.value
FROM data d JOIN regions r
ON d.gps_coords = r.gps_coords
WHERE d.metric = 5 AND r.region_id = 2
) b
ON b.gps_coords = a.gps_coords
AND a.year = b.year
GROUP BY a.gps_coords, a.year
ORDER BY a.gps_coords
| gps_coords | year | value |
| 506 | 2010 | 236.76 |
| 507 | 2010 | 0 |
| 508 | 2010 | 434.4 |
| 509 | 2010 | 45.24 |