Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Глюк не глюк с Postgres  [new]
vadim_maklakov
Member

Откуда: Санкт-Петербург
Сообщений: 2
Коллеги, всем привет!
Заметил тут любопытную вещь
Итого изучаю самостостоятельно SQL по книжке Alan Beaulieu Learning SQL 3edition
Не планирую быть DBA, смотрю в сторону DS которым нужен SQL для извлечения данных с их последующей обработкой.
Поставил на Linux из репо постгресса 12 версию, потом она проапгрейдилась до 13, но на 13 версию базу не перетаскивал, база сама крутится под 12.4
вот данные по версии сервера
===========================
postgres@debian:/home/mvg$ psql
psql (13.0 (Debian 13.0-1.pgdg100+1), server 12.4 (Debian 12.4-1.pgdg100+1))
Type "help" for help.
===========================
поставил dvdrental и набиваю руку на запросах через DBeaver плагин Eclipse
Заметил один не обычный баг (или не баг)
Глава 11, оператор CASE, раздел Case Expression Examples

Оригинал запроса на MySQL
автор
SELECT
monthname(rental_date) rental_month, count(*) num_rentals
FROM
rental
WHERE rental_date BETWEEN '2005-05-01' AND '2005-08-01' GROUP BY monthname(rental_date);


Переводим в Postgres меняя monthname(rental_date) -> TO_CHAR(rental_date, 'Month' )

автор
SELECT
TO_CHAR(rental_date, 'Month' ) AS "Month", COUNT(*) AS num_rentals
FROM
rental AS r
WHERE
rental_date BETWEEN '2005-05-01' AND '2005-08-01'
GROUP BY "Month";

Запускаем запрос, выдает все как в книжке

автор
Month | num_rentals
------------+-------------
June | 2311
May | 1156
July | 6709


Далее автор хочет показать как можно транспонировать вывод выше при помощи CASE, по образцу и подобию ранее конвертим monthname(rental_date) -> TO_CHAR(rental_date, 'Month' )
автор
SELECT
SUM (
CASE
WHEN TO_CHAR(rental_date, 'Month') = 'May' THEN 1
ELSE 0
END
) AS May_rentals,
SUM (
CASE
WHEN TO_CHAR(rental_date, 'Month') = 'June' THEN 1
ELSE 0
END
) AS June_rentals,
SUM (
CASE
WHEN TO_CHAR(rental_date, 'Month') = 'July' THEN 1
ELSE 0
END
) AS July_rentals
FROM rental AS r
WHERE rental_date BETWEEN '2005-05-01' AND '2005-08-01';

Вывод почему то нулевой без ошибок

автор
may_rentals | june_rentals| july_rentals
-----------------------------------------------------
0 | 0 | 0


берем и меняем TO_CHAR(rental_date, 'Month') -> TO_CHAR(rental_date, 'Mon')
правим запрос
автор
SELECT
SUM (
CASE
WHEN TO_CHAR(rental_date, 'Mon') = 'May' THEN 1
ELSE 0
END
) AS May_rentals,
SUM (
CASE
WHEN TO_CHAR(rental_date, 'Mon') = 'Jun' THEN 1
ELSE 0
END
) AS June_rentals,
SUM (
CASE
WHEN TO_CHAR(rental_date, 'Mon') = 'Jul' THEN 1
ELSE 0
END
) AS July_rentals
FROM rental AS r
WHERE rental_date BETWEEN '2005-05-01' AND '2005-08-01';

Вывод абсолютно другой, правильный вывод
автор
may_rentals | june_rentals | july_rentals
-----------------------------------------------------
1 156 | 2 311 | 6 709

Так что будьте бдительны...Может кому то будет полезно
9 ноя 20, 21:22    [22229111]     Ответить | Цитировать Сообщить модератору
 Re: Глюк не глюк с Postgres  [new]
Kr_Yury
Member

Откуда: Киев, Украина
Сообщений: 244
vadim_maklakov, TO_CHAR(rental_date, 'Month') возвращает строку длиной 9 символов. Более короткие значения дополнены справа пробелами. То есть требуется либо усечь левое значение TRIM(TO_CHAR(rental_date, 'Month')), либо дополнить правое пробелами до 9 сиволов
9 ноя 20, 21:46    [22229123]     Ответить | Цитировать Сообщить модератору
 Re: Глюк не глюк с Postgres  [new]
vadim_maklakov
Member

Откуда: Санкт-Петербург
Сообщений: 2
Юрий, большое спасибо за подсказку...
Просто когда-то прогонял этот запрос на MySQL 8 - все работало без проблем, и в мозгу так и отложилось что должно работать без проблем
Век живи - век учись и читай мануалы
Модераторы, плиз переименуйте тему в использование TRIM с TO_CHAR или снесите если никому она больше не интересна

автор
SELECT
SUM (
CASE
WHEN TRIM(TO_CHAR(rental_date, 'Month')) = 'May' THEN 1
ELSE 0
END
) AS May_rentals,
SUM (
CASE
WHEN TRIM (TO_CHAR(rental_date, 'Month')) = 'June' THEN 1
ELSE 0
END
) AS June_rentals,
SUM (
CASE
WHEN TRIM(TO_CHAR(rental_date, 'Month')) = 'July' THEN 1
ELSE 0
END
) AS July_rentals
FROM rental AS r
WHERE rental_date BETWEEN '2005-05-01' AND '2005-08-01';

Вывод сейчас правильный
may_rentals | june_rentals | july_rentals
-----------------------------------------------------
1 156 | 2 311 | 6 709

9 ноя 20, 22:48    [22229157]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить