2012-02-19 5 views
0

Предположим, что у меня есть следующие две таблицы:Tricky: слева присоединиться отношение со значением строки

PRICE 
price_id price  room_id  nr_of_people 
1   80   1   1 
2   75   1   2 
3   90   2   2 
4   120   3   3 


ROOM 
room_id  room_no  max_people 
1   101   2 
2   102   3 
3   103   4 

И, мне нужно следующий результат:

QUERY_RESULT 
price  room_no  nr_of_people 
80   101   1 
75   101   2 
0   102   1 
90   102   2 
0   102   3 
0   103   1 
0   103   2 
120   103   3 
0   103   4 

Хитрость здесь, я необходимо получить цену для каждого человека (для 2 человек, для 3 человек, для 4 человек, что увеличивается до max_people, определенных в таблице номеров), если в таблице цен нет фактических данных, он должен заполнить 0 по умолчанию. Вышеупомянутая иллюстрация должна поддержать мое объяснение.

Я не уверен, имеет ли структура таблицы логическую ошибку.

Любые мысли/ввод/помощь относительно того, как решить проблему, очень ценятся.

+0

Что ваш текущий оператор SQL, который вы используете? – FluffyKitten

+0

Это очень упрощенное подмножество того, что у меня есть в моей базе данных. Это часть заявки на бронирование отелей, где я определяю цену для каждой комнаты с разными параметрами в таблице данных с поворотным столом. Таким образом, can not действительно предоставляет какой-либо практический запрос для этой части, поскольку я не имею в настоящее время один. – code90

+0

Я ценю этот код90, но если вы не можете дать практический пример своего запроса, то мы не сможем предложить практическое решение :-) – FluffyKitten

ответ

1

Как ответ abresas и комментарии xQbert указывают, вам как-то нужно создать данные, чтобы присоединиться к ним с вашими таблицами.

Как ответ abresas, я использую вспомогательную таблицу, но в моем решении эта таблица должна быть заполнена только номерами от 1 до N, где N = наибольшее значение, которое может появиться в столбце max_people.

Я создал вспомогательную таблицу под названием aux с одной колонкой num. Этот запрос работает для меня:

SELECT IF(price.price IS NULL, 0, price.price) AS price, room.room_no, aux.num AS nr_of_people 
FROM room 
JOIN aux ON aux.num <= room.max_people 
LEFT JOIN price ON (price.room_id = room.room_id 
AND aux.num = price.nr_of_people) 
ORDER BY room.room_id, num 

К сожалению, MySQL не обеспечивает родной механизм для генерации последовательности целых чисел (см thesequestions), поэтому физически создать вспомогательную таблицу, как представляется, наиболее практичным способом для достижения что вам нужно, хотя обходные пути, безусловно, существуют, если вы действительно не можете или не хотите создавать такую ​​таблицу.

Просто для удовольствия, следующее будет работать без создания новой таблицы (все вдохновленный в вопросы, которые я связан с):

SELECT [...] 
FROM room 
JOIN (
    SELECT 1 num 
    UNION SELECT 2 
    UNION SELECT 3 
    UNION SELECT 4 
    -- ...add as many entries as needed... 
) aux ON aux.num <= room.max_people 
LEFT JOIN [...] 

Как хорошо, как это:

SELECT [...] 
FROM room 
JOIN (
    SELECT @row := @row +1 AS num 
    FROM any_table_that_is_big_enough, (SELECT @row :=0) r 
) aux ON aux.num <= room.max_people 
LEFT JOIN [...] 
+0

Hi Jong Bor, это прекрасно работает и, кажется, лучший подход для моей ситуации. Я ценю вашу помощь, я помечаю это, как только я успешно внедрю его в свой фактический код. Благодаря !!! – code90

+0

Вспомогательная таблица чисел полезна во многих случаях. –

+0

После долгих много часов на этом без всяких успехов, чтобы увидеть весь стол, работающий так, как он был предназначен, - это большое облегчение :)) Еще раз спасибо .. – code90

1

Вы должны создать таблицу, в которой у вас есть nr_of_people от 1 до max_people для каждой комнаты, и room_id. Затем вы можете сделать ВНУТРЕННУЮ РАБОТУ, чтобы получить информацию, как вы просили.

Вы также можете создать его как временную таблицу, создающую запрос с данными, необходимыми в вашем коде.

mysql> CREATE TEMPORARY TABLE nr (nr_of_people int, room_id int); 
Query OK, 0 rows affected (0.00 sec) 

mysql> INSERT INTO nr VALUES (1, 1), (2, 1), (1, 2), (2, 2), 
(3, 2), (1, 3), (2, 3), (3, 3), (4, 3); 
Query OK, 9 rows affected (0.00 sec) 
Records: 9 Duplicates: 0 Warnings: 0 

mysql> SELECT price.price, room.room_no, nr.nr_of_people 
FROM price 
RIGHT OUTER JOIN nr ON price.room_id = nr.room_id AND price.nr_of_people = nr.nr_of_people 
INNER JOIN room ON nr.room_id = room.room_id; 
+-------+---------+--------------+ 
| price | room_no | nr_of_people | 
+-------+---------+--------------+ 
| 80 |  101 |   1 | 
| 75 |  101 |   2 | 
| NULL |  102 |   1 | 
| 90 |  102 |   2 | 
| NULL |  102 |   3 | 
| NULL |  103 |   1 | 
| NULL |  103 |   2 | 
| 120 |  103 |   3 | 
| NULL |  103 |   4 | 
+-------+---------+--------------+ 
9 rows in set (0.00 sec) 
+0

привет, спасибо большое за ваше время и помощь. это работает отлично, но для этого требуется, чтобы я вводил числа до max_number для каждой комнаты, что на самом деле хорошо, но решение Jong Bor подходит лучше, так как в таблице требуется неклассифицированная последовательная нумерация в таблице. Спасибо, anyways .. – code90