SQL естественное объединение POSTGRES - PullRequest
2 голосов
/ 25 февраля 2010

Я не уверен, какое объединение мне нужно, потому что я не знаком с попытками перекрытия данных таким образом или, если это вообще возможно.

У меня есть две таблицы, которые обе имеют одинаковыенабор данных и оба связаны с 3-й родительской таблицей через Room_id.

У меня есть таблица Room_rates, в которой хранятся средние цены для каждой комнаты (room_id)

+-------+---------+-----------+-------+--------+---------------------------+---------------------------+
| id    | room_id | dayofweek | price | source | created_at                | updated_at                |
+-------+---------+-----------+-------+--------+---------------------------+---------------------------+
| 87936 | 2517    | 0         | 14.58 | 1      | 2010-02-22 17:47:14 +0100 | 2010-02-22 17:47:14 +0100 |
| 87937 | 2517    | 1         | 14.58 | 1      | 2010-02-22 17:47:14 +0100 | 2010-02-22 17:47:14 +0100 |
| 87938 | 2517    | 2         | 14.52 | 1      | 2010-02-22 17:47:14 +0100 | 2010-02-22 17:47:14 +0100 |
| 87939 | 2517    | 3         | 14.52 | 1      | 2010-02-22 17:47:14 +0100 | 2010-02-22 17:47:14 +0100 |
| 87940 | 2517    | 4         | 14.52 | 1      | 2010-02-22 17:47:15 +0100 | 2010-02-22 17:47:15 +0100 |
| 87941 | 2517    | 5         | 14.4  | 1      | 2010-02-22 17:47:15 +0100 | 2010-02-22 17:47:15 +0100 |
| 87942 | 2517    | 6         | 14.63 | 1      | 2010-02-22 17:47:15 +0100 | 2010-02-22 17:47:15 +0100 |
+-------+---------+-----------+-------+--------+---------------------------+---------------------------+

И таблицаВызовы с доступными тарифами на определенные даты

+--------+-------+-------+------------+---------+---------------------------+---------------------------+--------+
| id     | price | spots | bookdate   | room_id | created_at                | updated_at                | source |
+--------+-------+-------+------------+---------+---------------------------+---------------------------+--------+
| 221389 | 14.3  | 1     | 2010-03-01 | 2517    | 2010-02-21 22:31:06 +0100 | 2010-02-21 22:31:06 +0100 | 1      |
| 221390 | 14.3  | 1     | 2010-03-02 | 2517    | 2010-02-21 22:31:06 +0100 | 2010-02-21 22:31:06 +0100 | 1      |
| 221391 | 14.3  | 1     | 2010-03-03 | 2517    | 2010-02-21 22:31:06 +0100 | 2010-02-21 22:31:06 +0100 | 1      |
| 221392 | 14.3  | 1     | 2010-03-04 | 2517    | 2010-02-21 22:31:06 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
| 221393 |       | 0     | 2010-03-05 | 2517    | 2010-02-21 22:31:06 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
| 221394 |       | 0     | 2010-03-06 | 2517    | 2010-02-21 22:31:06 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
| 228185 |       | 0     | 2010-03-07 | 2517    | 2010-02-22 17:47:19 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
| 228186 | 14.3  | 1     | 2010-03-08 | 2517    | 2010-02-22 17:47:19 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
| 228187 | 14.3  | 1     | 2010-03-09 | 2517    | 2010-02-22 17:47:19 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
| 228188 | 14.3  | 1     | 2010-03-10 | 2517    | 2010-02-22 17:47:19 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
+--------+-------+-------+------------+---------+---------------------------+---------------------------+--------+

В настоящее время я использую два отдельных результата поиска, либо текущие данные Availables для определенного диапазона дат существуют, либо их нет.Если это не так, я использую запрос резервного копирования, используя только Room_rate средние значения.

Я хотел бы использовать Доступные, где есть доступные цены, но каким-то образом присоединиться к Room_rate, чтобы заполнить пробелы, если цена недоступна.или, возможно, нет никакой записи вообще.

Как мне это сделать?

Ответы [ 2 ]

4 голосов
/ 25 февраля 2010

Функция COALESCE может быть объединена с объединением, чтобы получить то, что вы хотите:

SELECT COALESCE(a.price, rr.price) 
  FROM Availables AS a
  FULL OUTER JOIN room_rates AS rr
    ON a.room_id = rr.room_id
  WHERE a.room_id=[id]
    AND a.bookdate=[date]
    AND rr.dayofweek=[dayofweek]

Вам понадобятся индексы в соответствующих столбцах, чтобы это выполнялось. Вам также нужно сравнить план выполнения этого оператора с альтернативами (такими как UNION, предложенный Бруно), чтобы увидеть, стоит ли объединение.

2 голосов
/ 25 февраля 2010

Это не относится к объединению. Объединение будет сопоставлять данные из таблицы с данными из другой таблицы. Например, для сопоставления room и room_rate вы бы использовали соединение. Но вы не хотите совпадать с Available и Room_rate. Вы хотите получить ставку от Доступно или - если не найдено в Avaiable - от Room_rate.

Итак, вам действительно нужно сначала выполнить запрос на Available, а затем запрос на Room_rate, если необходимо.

Вы можете получить первый результат, возвращаемый запросом, который выглядит примерно так:

select price from Availables where room_id=[id] and bookdate=[date]
union
select price from room_rates where room_id=[id] and dayofweek=[day of week]

Но я бы не советовал этого делать, потому что второй "select" будет запущен, даже если он не нужен. Поэтому лучше запускать первый выбор, а затем второй выбор, только если это необходимо.

...