SQL естествено присъединяване към POSTGRES

Не съм сигурен от какъв вид присъединяване се нуждая, тъй като не съм запознат с опитите за припокриване на данни по такъв начин или дали изобщо е осъществимо.

Имам две таблици, които споделят подобен набор от данни и са свързани с трета родителска таблица през 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_rates, за да попълня празните места, ако цената не е налична или евентуално изобщо няма запис.

Как мога да постигна това?


person holden    schedule 25.02.2010    source източник


Отговори (2)


Функцията 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, предложено от Бруно), за да видите дали присъединяването си заслужава.

person outis    schedule 25.02.2010

Това не е така за присъединяване. Обединяването ще съпостави данни от таблица с данни от друга таблица. Например, за съпоставяне на room и room_rates бихте използвали присъединяване. Но не искате да съпоставите Налични и Room_rates. Искате да получите тарифата от Available или - ако не е намерена в Avaiable - от 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]

Но аз наистина не бих го препоръчал, защото вторият "select" ще се изпълнява дори и да не е необходим. Така че е по-добре да стартирате първото избиране и след това второто избиране само ако е необходимо.

person b.roth    schedule 25.02.2010