Wolfnsex
@Wolfnsex
Если не хочешь быть первым - не вставай в очередь!

Как проверить массив на то, что все значения IS NULL?

В процессе решения вопроса: выводить NULL, если все значения в массиве (результата) IS NULL (вместо массива с NULL'ами). В итоге получилось следующее выражение:
SELECT ...
CASE WHEN ('A' = ALL(ARRAY_AGG(t1.value)) IS NULL) THEN null ELSE ARRAY_AGG(t1.value)

Тип данных в массиве — VARCHAR. Но, я не могу понять, что значит 'A' = ... Если мы проверяем массив с числами — можно писать 1 = или 999 = — работает одинаково... собственно "А" я тоже "от балды" написал и оно работает.
Не могу понять, что это за конструкция и как её правильно понимать? Если ткнёте в документацию, где об этом пишут или подскажите как правильно проверять массив на "все значения IS NULL" или объясните кратенько как работает это выражение — будут крайне признателен.
  • Вопрос задан
  • 278 просмотров
Решения вопроса 1
erge
@erge
Примус починяю
не знаю как вы сделали объединение по своему прошлому вопросу, но надо было сначала отобрать уникальные записи из первой таблицы, а затем уже заджойнить к ней вторую таблицу и агрегировать value в массив, тогда там где во второй таблице ничего нет к первой в массиве всего лишь один элемент null, соответственно берем первый элемент массива и смотрим его на null и т.д.

в-общем как-то так:

SELECT
  t.a1, t.a2, t.a3,
  CASE WHEN ( ARRAY_AGG(t2.value) )[1] IS null THEN null ELSE ARRAY_AGG(t2.value) END AS arr
FROM (
    SELECT 
      t1.a1,
      t1.a2,
      t1.a3
    FROM table1 t1
    GROUP BY t1.a1, t1.a2, t1.a3
  ) t
LEFT JOIN table2 t2 ON t.a1 = t2.b1 AND t.a2 = t2.b2 AND t.a3 = t2.b3
GROUP BY t.a1, t.a2, t.a3


но если в value второй таблицы будет null и этот элемент окажется первым, то это сработает и вернет null На весь массив.
можно было бы вставить проверку длины массива, но к сожалению по непонятным причинам функция ARRAY_LENGTH не работает (т.е. не найдена) ни у меня на pgsql 11 ни в sqlfiddle , как-то странно, а в доке пишут про нее... :??
но есть ARRAY_DIMS и тогда запрос можно переписать так:

SELECT
  t.a1, t.a2, t.a3,
  CASE WHEN
          (ARRAY_DIMS(ARRAY_AGG(t2.value)) = '[1:1]')
      AND ( ARRAY_AGG(t2.value) )[1] IS null
    THEN null ELSE ARRAY_AGG(t2.value)
  END AS arr
FROM (
    SELECT 
      t1.a1,
      t1.a2,
      t1.a3
    FROM table1 t1
    GROUP BY t1.a1, t1.a2, t1.a3
  ) t
LEFT JOIN table2 t2 ON t.a1 = t2.b1 AND t.a2 = t2.b2 AND t.a3 = t2.b3
GROUP BY t.a1, t.a2, t.a3


т.е. собственно ответ:
CASE WHEN
          (ARRAY_DIMS(ARRAY_AGG(t2.value)) = '[1:1]')
      AND ( ARRAY_AGG(t2.value) )[1] IS null
    THEN null ELSE ARRAY_AGG(t2.value)
  END
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы