mysql
  • count
  • chat
  • aggregate
  • having
  • 2012-05-25 2 views 1 likes 
    1

    У меня есть следующая функцияMYSQL HAVING ГДЕ не работает

    function availableChatRoom($topic_id){ 
    $max_rooms = 2; 
    $max_users = 2; 
    
    $sqli = "SELECT COUNT(DISTINCT room_num) AS numRooms FROM forum_chat WHERE topic_id = '$topic_id'"; 
    $num_rooms = queryColumnVal($sqli, "numRooms"); 
    
    $sqlii = "SELECT room_num, COUNT(user_id) AS numUsers FROM forum_chat 
          WHERE topic_id = '$topic_id' AND (status = 'online' AND status = 'offline') AND chat_msg = '' 
          GROUP BY room_num 
          HAVING numUsers < $max_users ORDER BY msg_date"; 
    
    $num_rooms_with_spaces = mysqlNumRows($sqlii, "room_num"); 
    queryColumnVal($sqlii, "room_num"); 
    
    if($num_rooms == 0){ 
        return 1; 
    } 
    elseif($num_rooms <= $max_rooms){ 
    
        if($num_rooms_with_spaces == 0){ 
         return $num_rooms + 1; 
        } 
        else{ 
         return queryColumnVal($sqlii, "room_num"); 
        } 
    } 
    else{ 
        return "none"; 
    } 
    

    }

    идея для функции, чтобы вернуть номер-чат с пространством. - Каждый раз, когда пользователь присоединяется к комнате, строка без msg вставлена ​​со статусом онлайн -Все время, когда пользователь выходит из комнаты, строка без msg вставлена ​​со статусом в автономном режиме Теперь я пытаюсь написать функцию, которая проверяет если для каждой темы есть свободные комнаты Идея состоит в том, чтобы выбрать room_num, где количество пользователей, которые вошли в систему, но не вышли из системы, меньше, чем максимальная болтовня в комнате. Может кто-нибудь помочь мне с моей $ sqlii.

    Благодаря

    ответ

    1

    Есть несколько ошибок в вашем запросе:

    • (status = 'online' AND status = 'offline')

    Это утверждает, что ваш запрос Виль возврата нет теперь у всех. Использование: (status = 'online' OR status = 'offline') или эквивалент (status IN ('online', 'offline'))

    • COUNT(user_id)

    Это не учитывает разницу пользователей онлайн минус оффлайн. Исправьте логику.

    • ORDER BY msg_date

    В GROUP BY запросов, это не хорошо использовать не совокупный столбец, в HAVING, SELECT или ORDER BY статей, несмотря на то что MySQL позволяет. Если этот столбец не зависит от выражения группировки. Поскольку msg_date явно не зависит от room_num, следует заменить, что с агрегатной функцией:

    ORDER BY MAX(msg_date) или ORDER BY MIN(msg_date)


    $sqlii = " 
        SELECT room_num, 
          COUNT(CASE WHEN status = 'online' THEN 1 END) 
          - COUNT(CASE WHEN status = 'offline' THEN 1 END) 
          AS numUsers 
        FROM forum_chat 
        WHERE topic_id = '$topic_id' 
        AND status IN ('online', 'offline') 
        AND chat_msg = '' 
        GROUP BY room_num 
        HAVING COUNT(CASE WHEN status = 'online' THEN 1 END) 
          - COUNT(CASE WHEN status = 'offline' THEN 1 END) 
          < $max_users 
        ORDER BY MAX(msg_date) 
        "; 
    
    +0

    Спасибо, я думал, что это будет сложнее ... работает так, как я хотел. Любые советы о том, где я могу изучать расширенные запросы, подобные этому? Это серьезный материал. – JamesBondInBlack

    +0

    @JamesBondInBlack, Возможно http://dba.stackexchange.com/questions/4821/best-book-to-learn-mysql и http://dba.stackexchange.com/questions/3740/suggest-a-mysql-book -for-me/3749 # 3749? – Pacerier

    0

    Вы не можете использовать псевдоним столбца в HAVING в том же SELECT уровне. Это потому, что в вас будет активирован MySQL ONLY_FULL_GROUP_BY.

    Попробуйте это -

    HAVING COUNT(user_id) < $max_users ORDER BY msg_date 
    
    2

    В HAVING clause будет оценивали перед SELECT, - поэтому сервер Безразлично» Еще не знаю об этом псевдониме.

    SELECT room_num, COUNT(user_id) AS numUsers 
    FROM forum_chat 
    WHERE topic_id = '$topic_id' AND 
         (status = 'online' OR status = 'offline') AND 
         chat_msg = '' 
    GROUP BY room_num 
    HAVING COUNT(user_id) < $max_users ORDER BY msg_date 
    
    1. Сначала произведение всех таблиц в from clause формируется.
    2. Затем оценивается where clause, чтобы исключить строки, которые не удовлетворяют условию search_condition.
    3. Затем строки сгруппированы с использованием столбцов в group by clause.
    4. Затем группы, которые не удовлетворяют условию search_condition в having clause, устраняются.
    5. Затем вычисляются выражения в целевом списке select clause.
    6. Если выделенное ключевое слово присутствует в предложении select, теперь удаляются повторяющиеся строки.
    7. Объединение берется после оценки каждого подвыбора. 8. Наконец, результирующие строки сортируются в соответствии с столбцами, указанными в предложении order by.
    +1

    На самом деле MySQL немного прощает и позволяет использовать псевдонимы из списка SELECT, которые будут использоваться в предложении HAVING. Но это определенно не в стандартном SQL. –

    +0

    спасибо за информацию :) –

    +0

    Просто хотел сказать спасибо, но это не сработало. Я пробовал это первым, потому что я понимаю логику, но спасибо в любом случае – JamesBondInBlack

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