Использование VALUES или CASE для повышения читаемости результатов

Иногда при построении запроса с помощью исследователя данных вы можете обнаружить, что в результатах используются коды вместо их текстовых эквивалентов. У поля часто есть ключ в дереве исследователя данных, но эти коды не всегда удобны при просмотре результатов (если только вы не запомнили их все :slight_smile:).

Есть несколько способов сделать их более удобными для восприятия и гораздо более удобными для обмена с другими.

Во-первых…

VALUES

Первый запрос был создан для получения всех уведомлений, полученных пользователем по конкретной теме, но вместо вывода только кода notification_type используется VALUES для создания временной таблицы и сопоставления каждого кода с его гораздо более понятным для человека эквивалентом:

-- Определите параметры для user_id и topic_id
-- [params] 
-- user_id :user_id
-- topic_id :topic_id

-- Создайте общее табличное выражение (CTE) с именем ntypes
-- Это CTE сопоставляет имена типов уведомлений с их соответствующими идентификаторами
WITH ntypes(notification_type, notification_type_id) AS (
  VALUES
    -- Определите пары типов уведомлений и их соответствующих идентификаторов
    ('mentioned', 1),
    ('replied',2),
    ('quoted',3),
    ('edited', 4),
    ('liked', 5),
    ('private_message', 6),
    ('invited_to_private_message', 7),
    ('invitee_accepted', 8),
    ('posted', 9),
    ('moved_post', 10),
    ('linked', 11),
    ('granted_badge', 12),
    ('invited_to_topic', 13),
    ('custom', 14),
    ('group_mentioned', 15),
    ('group_message_summary', 16),
    ('watching_first_post', 17),
    ('topic_reminder', 18),
    ('liked_consolidated', 19),
    ('post_approved', 20),
    ('code_review_commit_approved', 21),
    ('membership_request_accepted', 22),
    ('membership_request_consolidated', 23),
    ('bookmark_reminder', 24),
    ('reaction', 25),
    ('votes_released', 26),
    ('event_reminder', 27),
    ('event_invitation', 28),
    ('chat_mention', 29),
    ('chat_message', 30),
    ('chat_invitation', 31),
    ('chat_group_mention', 32),
    ('chat_quoted', 33),
    ('assigned', 34),
    ('question_answer_user_commented', 35), 
    ('watching_category_or_tag', 36),
    ('new_features', 37),
    ('admin_problems', 38),
    ('following', 800), 
    ('following_created_topic', 801),
    ('following_replied', 802),
    ('circles_activity', 900)
)
-- Запросите таблицу уведомлений (алиас n), присоединив её к CTE ntypes на основе notification_type
SELECT user_id, ntypes.notification_type, read, topic_id, created_at
FROM notifications n
JOIN ntypes
ON n.notification_type = ntypes.notification_type_id
-- Отфильтруйте уведомления, чтобы включить только те, которые принадлежат конкретному пользователю и конкретной теме
WHERE user_id = :user_id
AND topic_id = :topic_id
-- Отсортируйте полученные уведомления по убыванию временной метки created_at
ORDER BY created_at DESC

Использование VALUES полезно, когда список длинный, так как это может сделать запрос более читаемым. Это также позволяет связать созданную новую временную таблицу с другой, что может быть очень удобно. Временная таблица также может помочь повысить эффективность по сравнению с серией операторов CASE.

Что приводит нас ко второму…

CASE

Или, если список намного короче, вы также можете использовать CASE для аналогичного эффекта. Вот пример для post_type:

-- [params]
-- topic_id :topic_id

SELECT p.id AS post_id,
 -- Начало оператора CASE для сопоставления числовых кодов post_type с текстовыми описаниями
        CASE 
          WHEN post_type = 1 THEN 'regular'
          WHEN post_type = 2 THEN 'moderator_action'
          WHEN post_type = 3 THEN 'small_action'
          WHEN post_type = 4 THEN 'whisper'
        END
FROM posts p
WHERE p.topic_id = :topic_id
ORDER BY created_at DESC

Эти примерные запросы сами по себе могут быть не очень полезны, но они служат для демонстрации принципов. Надеюсь, они помогут, но если у вас возникнут вопросы, пожалуйста, задайте их ниже. :slight_smile:

13 лайков