0

我有以下表格:

几何学

| ID | GEOID | YEAR | VALUE |
|  1 |   100 | 2010 |    76 |
|  2 |   100 | 2020 |     1 |
|  3 |   101 | 2010 |    73 |
|  4 |   101 | 2020 |   123 |
|  5 |   102 | 2010 |     4 |
|  6 |   102 | 2020 |    20 |

| YEAR |
| 2010 |
| 2020 |

地区

| ID | GEOID | REGION |
|  1 |   100 |      1 |
|  2 |   101 |      1 |
|  3 |   102 |      1 |
|  4 |   100 |      2 |
|  5 |   101 |      2 |
|  6 |   102 |      3 |

我想获得大地水准面、年份和区域 = 2 的值。这是我的 SQL:

SELECT DISTINCT reg.geoid, years.year, j.value
FROM regions AS reg, years
LEFT JOIN (
  SELECT geometry.geoid, geometry.year, geometry.value
  FROM geometry
  JOIN regions AS reg
  ON reg.geoid = geometry.geoid
  AND reg.region = 2
  ) AS j
ON j.year = years.year
WHERE reg.region = 1
AND reg.geoid = j.geoid

这给了我这个:

| GEOID | YEAR | VALUE |
|   100 | 2010 |    76 |
|   100 | 2020 |     1 |
|   101 | 2010 |    73 |
|   101 | 2020 |   123 |

但我想得到所有的大地水准面和所有年份。这就是我执行 LEFT JOIN 的原因,以便它返回 LEFT 表的所有行。我希望它会返回这个:

| GEOID | YEAR | VALUE |
|   100 | 2010 |    76 |
|   100 | 2020 |     1 |
|   101 | 2010 |    73 |
|   101 | 2020 |   123 |
|   102 | 2010 |  null |
|   102 | 2020 |  null |

我怎样才能做到这一点?

更新

这是上述数据的 SQLFiddle:http ://sqlfiddle.com/#!2/963c7/6

4

2 回答 2

3

我认为您的查询过于复杂。以下只是做一个left outer joinfrom geometryto regions。当 中的值不匹配时regions,则使用case语句返回NULL值:

SELECT g.geoid, g.year,
       (case when r.geoid is not null then g.value end) as value
FROM geometry g left outer join
     regions r
     ON r.geoid = g.geoid AND
        r.region = 2
order by geoid, year;
于 2013-09-04T01:36:28.190 回答
1

问题是您使用了 WHERE 子句,其中包含您尝试 LEFT JOIN 到的表。这使它像 INNER JOIN 语句一样工作。

具体来说AND reg.geoid = j.geoid

把它移到 JOIN 语句中,你可能会有更好的运气。当然,您的交叉连接不是很明确,并且会导致您给出的 SQL 出现错误,但以下方法将起作用:

SELECT DISTINCT regyears.geoid, regyears.year, j.value
FROM (
SELECT reg.geoid, reg.region, years.year
FROM @regions AS reg, @years AS years
) regyears
LEFT JOIN (
  SELECT geometry.geoid, geometry.year, geometry.value
  FROM @geometry AS geometry
  JOIN @regions AS reg
  ON reg.geoid = geometry.geoid
  AND reg.region = 2
  ) AS j
ON j.year = regyears.year
AND j.geoid = regyears.geoid
WHERE regyears.region = 1

我已经使用临时对象来测试它,因此@regions, @years, @geometry. 只需将它们替换为您的表名即可。

于 2013-09-04T01:38:05.797 回答