PostgreSQL Где считать условие - PullRequest
33 голосов
/ 14 ноября 2011

У меня следующий запрос в PostgreSQL:

SELECT 
    COUNT(a.log_id) AS overall_count
FROM 
    "Log" as a, 
    "License" as b 
WHERE 
    a.license_id=7 
AND 
    a.license_id=b.license_id 
AND
    b.limit_call > overall_count
GROUP BY 
    a.license_id;

Почему я получаю эту ошибку:

ОШИБКА: столбец "total_count" не существует

Структура моей таблицы:

License(license_id, license_name, limit_call, create_date, expire_date)
Log(log_id, license_id, log, call_date)

Я хочу проверить, достигла ли лицензия ограничения на количество звонков в конкретном месяце.

Ответы [ 2 ]

46 голосов
/ 14 ноября 2011
SELECT a.license_id, a.limit_call
     , count(b.license_id) AS overall_count
FROM   "License"  a
LEFT   JOIN "Log" b USING (license_id)
WHERE  a.license_id = 7 
GROUP  BY a.license_id  -- , a.limit_call  -- add in old versions
HAVING a.limit_call > count(b.license_id)

Основные точки

  • В версиях, предшествующих PostgreSQL 9.1, необходимо добавить limit_call к предложению GROUP BY.Начиная с версии 9.1, достаточно иметь первичный ключ в предложении GROUP BY.Примечания к выпуску для 9.1 :

    Разрешить столбцы, отличные от GROUP BY, в списке целей запроса, если первичный ключ указан в предложении GROUP BY

  • Ваше условие WHERE должно перейти к предложению HAVING, так как оно относится к результату статистической функции.И вы не можете ссылаться на выходные столбцы (псевдонимы столбцов) в предложении HAVING, где вы можете ссылаться только на входные столбцы.Таким образом, вы должны повторить выражение. Согласно документации:

    Имя выходного столбца может использоваться для ссылки на значение столбца в предложениях ORDER BY и GROUP BY, но не в WHERE или HAVING статьи;вместо этого вы должны выписать выражение.

  • Я изменил порядок таблиц в предложении FROM и немного очистил синтаксис, чтобы сделать его менее запутанным.USING - это просто условное обозначение.

  • Я использовал LEFT JOIN вместо JOIN, поэтому вы не исключаетелицензии без каких-либо журналов.

  • Я бы посоветовал не использовать идентификаторы смешанного регистра в Postgres, если это возможно,Очень подвержен ошибкам.

  • Только ненулевые значения учитываются count().Поскольку вы хотите сосчитать связанных записей в таблице "Log", безопаснее и немного дешевле использовать count(b.license_id).Этот столбец используется в объединении, поэтому нам не нужно беспокоиться о том, может ли столбец быть нулевым или нет.
    count(*) еще короче и немного быстрее, но все же.Если вы не против получить счет 1 для 0 строк в левой таблице, используйте его.

6 голосов
/ 14 ноября 2011

Запрос where не распознает псевдоним вашего столбца, и, кроме того, вы пытаетесь отфильтровать строки после агрегации .Попробуйте:

SELECT 
COUNT(a.log_id) AS overall_count
FROM 
"Log" as a, 
"License" as b 
WHERE 
a.license_id=7 
AND 
a.license_id=b.license_id 
GROUP BY 
a.license_id
having b.limit_call > count(a.log_id);

Предложение having аналогично предложению where, за исключением того, что оно работает со столбцами после агрегации, тогда как предложение where работает со столбцами до агрегирования.

Кроме того, есть ли причина, по которой имена ваших таблиц заключены в двойные кавычки?

...