1

我们有一个获取 GPS 坐标数据的程序。我们可以根据数据库中的区域 id 获取数据集,如下所示:

gps_coords | year      | value
105        | 2010      |  5.63
102        | 1990      |  3.2
103        | 2000      |  13.23
...

现在,我们想将它与另一个查询集结合起来,使用 sqla.value + b.value(a.value+50)*b.value/100. 我们还按指标(他们想要查询的数据集)过滤我们的查询。

问题是如何将两个 gps_coords 检索为一列。我想我们必须JOIN在同一张桌子上做 a,但我不知道如何在同一列中同时获得 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  |

示例(不正确)SQL:

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 将包括坐标 506 和 509,并将与 rb.region 3 的坐标相加:506 和 508,添加在坐标 506)。507 不会出现在任何一个区域 id 中,因此它是 0 或 null,以两者为准。

4

2 回答 2

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 | 年份 | 价值 |
----------|--------|--------|
| 506 | 2010 | 236.76 |
| 507 | 2010 | 10.32 |
| 508 | 2010 | 462.9 |
| 509 | 2010 | 45.24 |

这是SQLFiddle演示

于 2013-08-26T05:38:15.013 回答
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  |
于 2013-09-02T02:37:46.673 回答