Хранимая процедура WHERE OR HAVING не работает

В приведенной ниже процедуре

Он выдает ошибку ([Err] 1111 — Недопустимое использование групповой функции), когда я использую операторы WHERE, и выдает другую ошибку ([Err] 1054 — Неизвестный столбец «roomid» в «имеющем предложении»), когда я использую операторы HAVING вместо WHERE. , хотя у меня есть столбец roomid, определенный в таблице.

Есть ли у кого-нибудь идеи о том, как я могу решить эту проблему? Код работал отлично, когда я пытался использовать другую версию mySQL, я думаю.

DELIMITER //
DROP PROCEDURE IF EXISTS `findAVG`//
CREATE DEFINER=`kamer`@`%` PROCEDURE `findAVG`(IN rid INT, startDate DATETIME, OUT Score DOUBLE)
BEGIN        
    DECLARE finishDate DATETIME; 
    DECLARE DateIterator DATETIME;
    DECLARE avgPrice DOUBLE;
    SET avgPrice = 0;
    SET Score = 0;
    SELECT price into Score 
    FROM bookings 
    WHERE roomid = rid 
    ORDER BY ABS( DATEDIFF( bookings.date, startDate)) LIMIT 1;

    IF (Score = 0) THEN 
        SET DateIterator = startDate;
        SET finishDATE = DATE_ADD(startDate,  INTERVAL 30 DAY); 
        WHILE DateIterator <=  finishDate DO
            SELECT price 
            INTO avgPrice 
            FROM prices 
            WHERE roomid = rid 
            AND date = DateIterator 
            ORDER BY DATEDIFF(startDate, prices.timestamp) LIMIT 1;   

            SET DateIterator = DATE_ADD(DateIterator,  INTERVAL 1 DAY);
        END WHILE;
        SET Score = AVG(avgPrice);
    END IF;

    UPDATE bookings SET price=Score WHERE roomid= rid AND date=startDate;
END

person Niklaus    schedule 29.12.2013    source источник
comment
Что вы ожидаете от AVG(avgPrice)?   -  person Rowland Shaw    schedule 29.12.2013
comment
Средние цены за 30 последующих дней данного roomid=rid, начиная с startDate. Однако, как я уже сказал, процедура работала только из-за изменения функции mySQL. Это дало вышеуказанную ошибку, недопустимое использование групповой функции. Затем, когда я изменил на HAVING, он выдал еще одну ошибку.   -  person Niklaus    schedule 29.12.2013
comment
Примечание. Каждый день существует несколько цен, поэтому он также берет самую последнюю, прежде чем брать среднее значение в соответствии с startDate.   -  person Niklaus    schedule 29.12.2013
comment
Допустим, значение avgPrice равно 3,14 (ведь оно определяется как двойное); среднее значение набора { 3.14 } равно 3,14 - вы можете переместить агрегацию в запрос   -  person Rowland Shaw    schedule 29.12.2013
comment
Уважаемый Rowland, спасибо за попытку помочь, но я не понял, что в этом плохого. Я не могу переместить агрегацию в запрос, поскольку я ограничиваю. Даже если я это сделаю, я не думаю, что это устранит ошибки, которые я получил. Я попробую прямо сейчас в любом случае. У вас есть решение для ошибок, которые я получаю? из-за операторов HAVING или WHERE.   -  person Niklaus    schedule 29.12.2013
comment
Я попробовал то, что вы рекомендовали, все еще говорит [Err] 1054 - Неизвестный столбец «roomid» в «имеющем предложении».   -  person Niklaus    schedule 29.12.2013
comment
HAVING AND WHERE не являются независимыми утверждениями. Это предложения операторов модификации данных, таких как SELECT, UPDATE или DELETE. В приведенном выше коде вы вызываете AVG(avgPrice) как часть простого оператора SET, что недопустимо.   -  person gwaigh    schedule 29.12.2013
comment
Да, вы правы, спасибо большое! Исправлено, когда я сделал avgPrice/30. Однако цены на некоторые даты могут отсутствовать и возвращать значение NULL. Как я могу взять среднее значение по avgPrice вместо того, чтобы напрямую погружать его в постоянное число?   -  person Niklaus    schedule 29.12.2013


Ответы (1)


«Недопустимое использование групповой функции» означает, что вы использовали столбец в группировке по функции, который не отображается в предложении select или наоборот.

i.e. :

SELECT A,B,C,COUNT(*) FROM mytable GROUP BY A,B,C

Группировка выполняется по трем первым столбцам, а подсчет ведется по каждой строке, где A, B и C похожи.

Например, если вы попытаетесь передать "GROUP BY A,B", SQL не будет знать, что делать со столбцом C...

Для проблемы HAVING мне кажется, что предложение HAVING применяется после того, как выбор был сделан. Поэтому, если вы используете столбец, которого нет в предложении SELECT, возникает ошибка.

person Taz    schedule 29.12.2013
comment
На самом деле MySql разрешает SELECT A,B,C,COUNT(*) FROM mytable GROUP BY A, но значения для B и C не определены. - person Rowland Shaw; 30.12.2013