JavaRush /Курси /SQL SELF /Порівняння та перетворення типів даних

Порівняння та перетворення типів даних

SQL SELF
Рівень 16 , Лекція 3
Відкрита

Навіщо взагалі все це потрібно — порівняння та перетворення типів? Уяви, у тебе в таблиці лежить рядок "42", а ти хочеш порівняти його з числом 42. На перший погляд — одне й те саме. Але для бази даних це можуть бути зовсім різні речі. PostgreSQL не буде автоматично здогадуватись, що ти мав на увазі. І якщо не розуміти, як саме він порівнює значення різних типів, можна отримати дивний результат або взагалі помилку.

Те саме стосується і перетворень. Іноді треба перетворити текст у число, щоб порахувати, скільки всього штук чогось там. А буває, навпаки — число треба красиво показати як рядок. Або взяти дату й вивести її у вигляді "01.01.2025", бо так звичніше користувачу.

Або ось ще приклад: у тебе точне значення зберігається в NUMERIC, але для наукових обчислень треба використовувати FLOAT. У таких випадках без явного перетворення — ніяк.

Гарна новина в тому, що PostgreSQL чудово з цим справляється. Він дає гнучкі й зрозумілі інструменти для таких задач. Головне — знати, як ними користуватись, і не боятись трохи зазирнути під капот. Цим і займемось.

Порівняння типів даних

PostgreSQL намагається бути розумним — якщо бачить, що порівнюються, скажімо, INTEGER і NUMERIC, він спокійно приведе їх до спільного знаменника і все порівняє. Це нормально, бо обидва — числа.

Але якщо ти вирішиш порівняти рядок з булевим значенням (TEXT і BOOLEAN), база даних вже не зрозуміє, чого ти від неї хочеш. У цих типів зовсім різна природа, і PostgreSQL просто видасть помилку. Те саме станеться, якщо ти спробуєш порівняти рядок "42" з числом 42, не вказавши явно, що хочеш цей рядок перетворити у число.

Як це виглядає на практиці? Ось приклад, який викличе помилку:

SELECT '42' = 42; -- Помилка! Рядок і число без перетворення не порівнюються

А ось так все спрацює як треба:

SELECT '42'::INTEGER = 42; -- TRUE

Тут ми явно кажемо: “Будь ласка, спочатку перетвори '42' у число”. Для цього і потрібен синтаксис ::Тип, про який ми вже згадували. PostgreSQL любить, коли з ним говорять чітко.

Порівняння числових типів

Числові типи даних (INTEGER, NUMERIC, REAL) найчастіше сумісні між собою, тому їх можна порівнювати без особливих складнощів:

SELECT 42 = 42.0; -- TRUE
SELECT 42::REAL = 42.0; -- TRUE
SELECT 42.0::NUMERIC = 42; -- TRUE

Але будь обережний з числами з плаваючою комою (REAL). Через обмежену точність такі числа можуть поводитись неочікувано. Наприклад:

SELECT 0.1 + 0.2 = 0.3; -- FALSE

Хіба це не найвідоміша загадка програмування? Тут порівняння повертає FALSE через особливості зберігання дробових чисел у пам’яті комп’ютера.

Порівняння текстових типів

Працюючи з текстовими типами, ти можеш порівнювати CHAR, VARCHAR і TEXT, бо PostgreSQL автоматично перетворює їх у сумісні типи:

SELECT 'Hello' = 'Hello'::TEXT; -- TRUE
SELECT 'World'::CHAR(5) = 'World'::VARCHAR; -- TRUE

Зверни увагу на довжину символів у CHAR(n): якщо рядок коротший за вказану довжину, PostgreSQL доповнить його пробілами.

Перетворення типів даних

PostgreSQL надає кілька способів перетворення типів даних. Розглянемо два основних методи:

Спосіб №1: Явне перетворення (CAST)

Оператор CAST дозволяє визначити, як треба перетворити один тип в інший. Ось приклад:

SELECT CAST('42' AS INTEGER); -- Перетворює рядок '42' у число 42

Цей метод особливо зручний, якщо ти хочеш зробити SQL-код більш читабельним.

Спосіб №2: Скорочений запис (::)

PostgreSQL пропонує альтернативний синтаксис для перетворення типів — використання ::. Це та сама операція, але записана коротше:

SELECT '42'::INTEGER; -- Те саме, що й CAST('42' AS INTEGER)

Автоматичне перетворення

У багатьох випадках PostgreSQL автоматично перетворює дані. Наприклад, використання чисел у текстових полях:

SELECT '42' = 42::TEXT; -- TRUE

Але покладатись на автоматичне перетворення не завжди безпечно, бо воно може бути неочікуваним для інших розробників. Наприклад, у випадках з датами й рядками краще використовувати явне перетворення.

Приклади перетворення різних типів даних

Перетворення чисел у текст

Іноді виникає потреба перетворити числа у текст (наприклад, для формування повідомлень):

SELECT 42::TEXT; -- Перетворює число 42 у рядок '42'
SELECT 3.14::TEXT; -- Перетворює число 3.14 у рядок '3.14'

Перетворення тексту у числа

Якщо у рядку міститься коректне число, ти можеш перетворити його у числовий тип:

SELECT '123'::INTEGER; -- Перетворює рядок '123' у число 123
SELECT '3.14'::FLOAT;  -- Перетворює рядок '3.14' у число 3.14

А що буде, якщо текст не піддається перетворенню? Наприклад:

SELECT 'Hello'::INTEGER; -- Помилка: неможливо перетворити 'Hello' у число

Щоб уникнути таких помилок, ти можеш використовувати функцію TRY_CAST() (починаючи з PostgreSQL 14) або попередньо перевіряти дані.

Перетворення дати у текст і навпаки

Для перетворення дат ти можеш використовувати функції TO_CHAR() і TO_DATE():

SELECT TO_CHAR(CURRENT_DATE, 'YYYY-MM-DD'); -- Перетворює дату у рядок
SELECT TO_DATE('2023-10-25', 'YYYY-MM-DD'); -- Перетворює рядок у дату

Перетворення між BOOLEAN і текстом

Логічний тип даних BOOLEAN теж можна перетворювати у рядки:

SELECT TRUE::TEXT; -- 'true'
SELECT FALSE::TEXT; -- 'false'

Або навпаки:

SELECT 'true'::BOOLEAN; -- TRUE
SELECT 'false'::BOOLEAN; -- FALSE

Зверни увагу, що рядки типу 'yes' чи 'no' не будуть перетворені автоматично.

Практика: все на реальних прикладах

Створимо таблицю, яка демонструє використання різних типів даних:

id number_as_text - TEXT number_as_integer - INTEGER date_as_text - TEXT actual_date - DATE
1 42 42 2023-10-25 2023-10-25
2 3.14 NULL 2023-10-24 NULL
3 Hello 123 NULL NULL

Тепер виконаємо операції перетворення:

-- Перетворення тексту у число
SELECT number_as_text::INTEGER FROM data_types_demo WHERE number_as_text = '42';

-- Перетворення дати у текст
SELECT TO_CHAR(actual_date, 'DD/MM/YYYY') FROM data_types_demo;

-- Перетворення рядка у дату
SELECT TO_DATE(date_as_text, 'YYYY-MM-DD') FROM data_types_demo;

Типові помилки при перетворенні даних

Типові помилки включають:

  1. Спроби перетворити дані, які не відповідають очікуваному формату (наприклад, рядок 'Hello' у INTEGER).
  2. Проблеми з округленням і точністю при роботі з числами з плаваючою комою.
  3. Некоректне використання форматів при перетворенні дат.

Щоб уникнути помилок, рекомендується:

  • Завжди перевіряти дані перед перетворенням.
  • Використовувати функції обробки помилок (TRY_CAST або CASE).
  • Вказувати формат явно при перетворенні дат.
-- Перевірка даних перед перетворенням
SELECT 
    CASE 
        WHEN number_as_text ~ '^\d+$' THEN number_as_text::INTEGER
        ELSE NULL
    END AS safe_integer
FROM data_types_demo;

Використовуй цей підхід, щоб захистити свої запити від неочікуваних ситуацій!

На цьому етапі ти вже маєш базові навички для порівняння та перетворення типів даних у PostgreSQL. Далі — тільки практика, практика і ще раз практика. Побачимось на наступних лекціях!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ