Mysql добавляет псевдонимы с осложнениями

Итак, я создал систему бронирования, и у меня возникли некоторые проблемы с некоторыми расчетами цен.

Первоначально у меня было

SELECT c_id, c_title, c_imgdrop, c_link, c_text4, 
    (SELECT SUM(bd_price) as price FROM booking_dates WHERE site_id = '15' AND bd_room_type IN ('single','double') AND bd_date IN ('2011-03-05') AND bd_h_id = c_id) AS sum_price
FROM c_content
JOIN (SELECT bd_h_id FROM booking_dates WHERE site_id = '15' AND bd_date IN ('2011-03-05') AND bd_available <= '1' AND bd_room_type = 'single' AND bd_price > '0' GROUP BY bd_h_id HAVING count(*) = '1' ) q_0 ON c_content.c_id = q_0.bd_h_id
JOIN (SELECT bd_h_id FROM booking_dates WHERE site_id = '15' AND bd_date IN ('2011-03-05') AND bd_available <= '1' AND bd_room_type = 'double' AND bd_price > '0' GROUP BY bd_h_id HAVING count(*) = '1' ) q_1 ON c_content.c_id = q_1.bd_h_id
WHERE site_id = '15'

Что сработало нормально, за исключением того, что это сработало не очень хорошо, если вы попытаетесь вычислить несколько типов комнат одного и того же типа.

В любом случае я попытался разделить запросы на типы номеров и умножить значение на количество номеров для этого типа в бронировании. Я использовал это ( Добавление полей псевдонимов MySQL вместе ), что означало, что мне нужно было добавить дополнительный уровень подзапросов, который немного запутал.

Я почти там сейчас, но он не распознает одно из имен полей в моих подзапросах, я ожидаю, из-за порядка, в котором он выполняет запрос.

Что у меня есть сейчас:

SELECT c_id, c_title, c_imgdrop, c_link, c_text4, 
    (SELECT sum_price_single, sum_price_double, sum_price_single + sum_price_double AS sum_price FROM
        (SELECT
            ((SELECT SUM(bd_price) as price FROM booking_dates WHERE site_id = '15' AND bd_room_type = 'single' AND bd_date IN ('2011-03-05') AND bd_h_id = c_id) * 1) AS sum_price_single,
            ((SELECT SUM(bd_price) as price FROM booking_dates WHERE site_id = '15' AND bd_room_type = 'double' AND bd_date IN ('2011-03-05') AND bd_h_id = c_id) * 1) AS sum_price_double
            FROM booking_dates
        )
    x)
FROM c_content
JOIN (SELECT bd_h_id FROM booking_dates WHERE site_id = '15' AND bd_date IN ('2011-03-05') AND bd_available <= '1' AND bd_room_type = 'single' AND bd_price > '0' GROUP BY bd_h_id HAVING count(*) = '1' ) q_0 ON c_content.c_id = q_0.bd_h_id
JOIN (SELECT bd_h_id FROM booking_dates WHERE site_id = '15' AND bd_date IN ('2011-03-05') AND bd_available <= '1' AND bd_room_type = 'double' AND bd_price > '0' GROUP BY bd_h_id HAVING count(*) = '1' ) q_1 ON c_content.c_id = q_1.bd_h_id
WHERE site_id = '15'

И дает мне следующую ошибку

Неизвестный столбец «c_id» в «где пункт»

Любые идеи? Это должно вывести список отелей (значения из таблицы c_content) и цену для каждого из них. Цена состоит из суммы различных дат, но также должна учитывать многоместные номера и смешанные типы номеров, которые также имеют разные цены.


person Horse    schedule 10.03.2011    source источник


Ответы (2)


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

Тем временем, я думаю, что-то вроде следующего должно решить вашу проблему с областью видимости.

SELECT *, sum_price_single + sum_price_double AS sum_price FROM (
    SELECT c_id, c_title, c_imgdrop, c_link, c_text4,
        (SELECT SUM(bd_price) * 1 as price FROM booking_dates WHERE site_id = '15' AND bd_room_type = 'single' AND bd_date IN ('2011-03-05') AND bd_h_id = c_id) AS sum_price_single,
        (SELECT SUM(bd_price) * 1 as price FROM booking_dates WHERE site_id = '15' AND bd_room_type = 'double' AND bd_date IN ('2011-03-05') AND bd_h_id = c_id) AS sum_price_double
    FROM c_content
    JOIN (SELECT bd_h_id FROM booking_dates WHERE site_id = '15' AND bd_date IN ('2011-03-05') AND bd_available <= '1' AND bd_room_type = 'single' AND bd_price > '0' GROUP BY bd_h_id HAVING count(*) = '1' ) q_0 ON c_content.c_id = q_0.bd_h_id
    JOIN (SELECT bd_h_id FROM booking_dates WHERE site_id = '15' AND bd_date IN ('2011-03-05') AND bd_available <= '1' AND bd_room_type = 'double' AND bd_price > '0' GROUP BY bd_h_id HAVING count(*) = '1' ) q_1 ON c_content.c_id = q_1.bd_h_id
    WHERE site_id = '15'
) AS t1

По сути, перемещение основных подвыборок вверх на два уровня и перенос «суммы» одинарного и двойного выбора во внешний выбор. Чтобы подтвердить, это не оптимально ... но это должно решить вашу насущную проблему. Я могу вернуться к проблеме после обеда: P

person Jeff Parker    schedule 10.03.2011
comment
Хорошо, я уже сделал, как вы сказали, и решил проблему на данный момент, однако это означало избавиться от псевдонимов для запросов о типе номера / цене и просто добавить их вместе, что означает, что я не смогу разделить цены на номера. если мне тоже нужно (о чем клиент буквально только что попросил). Я предпочитаю ваше решение :) Большое спасибо! - person Horse; 10.03.2011

Не окончательное решение, как предпочитает Джефф Паркерс, но вот запрос, который я использовал для его решения в краткосрочной перспективе.

SELECT c_id, c_title, c_imgdrop, c_link, c_text4,
((SELECT SUM(bd_price) as price FROM booking_dates WHERE site_id = '15' AND bd_room_type = 'single' AND bd_date IN ('2011-03-05') AND bd_h_id = c_id) * 1)
+
((SELECT SUM(bd_price) as price FROM booking_dates WHERE site_id = '15' AND bd_room_type = 'double' AND bd_date IN ('2011-03-05') AND bd_h_id = c_id) * 1) AS sum_price
FROM c_content
JOIN (SELECT bd_h_id FROM booking_dates WHERE site_id = '15' AND bd_date IN ('2011-03-05') AND bd_available <= '1' AND bd_room_type = 'single' AND bd_price > '0' GROUP BY bd_h_id HAVING count(*) = '1' ) q_0 ON c_content.c_id = q_0.bd_h_id
JOIN (SELECT bd_h_id FROM booking_dates WHERE site_id = '15' AND bd_date IN ('2011-03-05') AND bd_available <= '1' AND bd_room_type = 'double' AND bd_price > '0' GROUP BY bd_h_id HAVING count(*) = '1' ) q_1 ON c_content.c_id = q_1.bd_h_id
WHERE site_id = '15' ORDER BY sum_price desc 
person Horse    schedule 10.03.2011