Возврат нескольких значений в выражении CASE в подзапросе и разделение столбцов в основном запросе - PullRequest
0 голосов
/ 17 декабря 2018

Моя тестовая таблица выглядит так:

# select * from a;
 source | target | id
--------+--------+----
      1 |      2 |  1
      2 |      3 |  2
      3 |      0 |  3

Мой запрос такой:

SELECT *
FROM (
  SELECT
    CASE
      WHEN id<>1
      THEN source
      ELSE 0
      END
      AS source,
    CASE
      WHEN id<>1
      THEN target
      ELSE 0
      END
      AS target
  FROM a
) x;

Запрос кажется немного странным, потому что выражение CASE с теми же критериями повторяетсядля каждого столбца.Я хотел бы упростить это и попробовал следующее, но это не работает должным образом.

SELECT *
FROM (
  SELECT
    CASE
      WHEN id<>1
      THEN (source, target)
      ELSE (0, 0)
      END
      AS r
  FROM a
) x;

Это дает один столбец со значением строки, но я бы предпочел получить два исходных столбца.Разделение их с помощью (r). * Или подобного не работает, потому что «тип записи не зарегистрирован».

Я нашел несколько вопросов здесь с решениями относительно функций, возвращающих значения RECORD, но ни одного относительно этогопример с вложенным выбором.

На самом деле список столбцов довольно длинный, поэтому многократное повторение одного и того же выражения CASE делает весь запрос совершенно нечитабельным.

Поскольку настоящая проблема -в отличие от этого упрощенного случая, состоящего из нескольких выражений CASE и нескольких групп столбцов, решение с UNION не поможет, поскольку число UNION будет большим и сделает его нечитаемым, а также несколько CASE.

Мой актуальный вопрос: Как я могу получить исходные столбцы из значения строки?

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Это отвечает на оригинальный вопрос.Если я понял ваши потребности, вы хотите 0 и 0 для source и target, когда id = 1:

SELECT 
  0 AS source, 
  0 AS target 
FROM tablename 
WHERE id = 1
UNION ALL
SELECT 
  source, 
  target 
FROM tablename 
WHERE id <> 1
0 голосов
/ 17 декабря 2018

Исправленный ответ: Вы можете заставить ваш запрос работать (исправление типа записи не было зарегистрированной проблемой), создав TYPE:

CREATE TYPE stpair AS (source int, target int);

и приведя столбец составного значения к этому типу:

SELECT id, (cv).source, (cv).target
FROM (
    SELECT id, CASE
        WHEN id <> 1 THEN (source, target)::stpair
        ELSE (0, 0)::stpair
    END AS cv
    FROM t
) AS x

Сказав это, должно быть гораздо удобнее использовать массивы:

SELECT id, av[1] AS source, av[2] AS target
FROM (
    SELECT id, CASE
        WHEN id <> 1 THEN ARRAY[source, target]
        ELSE ARRAY[0, 0]
    END AS av
    FROM t
) AS x

Демонстрация на db <> fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...