2010-02-25 4 views
2

Я не уверен, какое соединение мне нужно, поскольку я не знаком с попыткой перекрытия данных таким образом, или если это даже возможно.SQL natural join POSTGRES

У меня есть две таблицы, которые и разделяют подобный набор данных и как относящиеся к 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  | 
+--------+-------+-------+------------+---------+---------------------------+---------------------------+--------+ 

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

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

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

ответ

2

Это не относится к объединению. Соединение будет сопоставлять данные из таблицы с данными из другой таблицы. Например, для сопоставления комнаты и room_rates вы должны использовать соединение. Но вы не хотите сопоставлять Available and Room_rates. Вы хотите получить ставку из доступных или - если не найдете в Avaiable - from Room_rates.

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

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

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] 

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

4

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] 

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

Смежные вопросы