Postgres: полное объединение на двух полях (проблема с пропуском данных)
У меня есть два подзапроса, которые создают эти таблицы:
date | name | data x
-----------+------+-------
2013-07-01 | a | 2
2013-07-01 | c | 3
2013-07-01 | d | 1
date | name | data y
-----------+------+-------
2013-07-01 | a | 13
2013-07-01 | b | 16
2013-07-01 | d | 20
Я хочу сделать полное объединение, используя дату и имя в качестве критерия соединения. (Дата не ограничена 2013-07-01, поэтому в действительности поле даты и поле имени образуют уникальное поле псевдоидентификатора.)
В идеале результат должен выглядеть примерно так:
date | name | data x | data y
-----------+------+--------+-------
2013-07-01 | a | 2 | 13
2013-07-01 | b | | 16
2013-07-01 | c | 3 |
2013-07-01 | d | 1 | 20
(Лучше всего, если я могу поставить нули для нуля, но об этом можно будет поговорить позже.)
Я использовал запрос, похожий на этот:
select
table1.date, table1.name, table1.dataX, table2.dataY
from table1
full join table2 on table1.date=table2.date and table1.name=table2.name
Postgres вводит только те поля, которые существуют в обеих таблицах (в этом примере только строки с именами a и c), что на самом деле лишает смысла полное соединение.
Я пробовал другой способ устранения неполадок, единственный, который работал до сих пор:
select
table1.date, table2.date, table1.name, table2.name, table1.dataX, table2.dataY
from table1
full join table2 on table1.date=table2.date and table1.name=table2.name
возвращает:
date |date | name | name | data x | data y
-----------+------------+------+------+--------+-------
2013-07-01 | 2013-07-01 | a | a | 2 | 13
| 2013-07-01 | | b | | 16
2013-07-01 | | c | | 3 |
2013-07-01 | 2013-07-01 | d | d | 1 | 20
Есть обходные пути, чтобы сделать это, когда я использую данные, но на самом деле это не идеально. Есть ли способ заставить запрос вернуть желаемый результат?
Потерять немного волос здесь. Огромное спасибо!
1 ответ
Не используйте WHERE
оговорка, но JOIN
состояние. USING
Статья пригодится:
SELECT the_date, name, t1.data_x, t2.data_y
FROM tbl1 t1
FULL JOIN tbl2 t2 USING (the_date, name);
Чтобы доказать свою точку зрения, это может быть сделано без USING
:
SELECT COALESCE(t1.the_date, t2.the_date) AS the_date
,COALESCE(t1.name, t2.name) AS name
,t1.data_x, t2.data_y
FROM tbl1 t1
FULL JOIN tbl2 t2 ON t1.the_date = t2.the_date
AND t1.name = t2.name
Может быть полезно для связанных запросов. Первый из них более элегантный, немного быстрее, а также стандартный SQL.
-> SQLfiddle (демонстрирует оба)