Postgresql — выберите в проблеме выбора псевдонима

#sql #arrays #postgresql #subquery #postgresql-12

#sql #массивы #postgresql #подзапрос #postgresql-12

Вопрос:

У меня есть запрос.

https://dbfiddle.uk/?rdbms=postgres_12amp;fiddle=1b3a39357a5fe028f57b9ac26d147a1d

 SELECT users.id as user_ids,
       (SELECT
           ARRAY_AGG(DISTINCT CONCAT(user_has_bonuses.bonus_id)) as bonus_ids
        FROM user_has_bonuses
            WHERE user_has_bonuses.user_id = users.id) as BONUS_IDS,
       (SELECT
           ARRAY_AGG(DISTINCT CONCAT(bonuses.bonus_id))
        FROM bonuses
            WHERE bonuses.bonus_id IN (BONUS_IDS)
            ) AS bonusIds
FROM users;
  

Я получаю сообщение об ошибке ниже:

[42703] ОШИБКА: столбец «bonus_ids» не существует Подсказка: возможно, вы имели в виду ссылку на столбец «bonuses.bonus_id».

Как я могу правильно использовать этот запрос?

Комментарии:

1. Таким образом, qery имеет мало смысла — по крайней мере, для меня. Что вы пытаетесь сделать? Какие результаты вы ожидаете?

2. Спасибо. У меня есть много связанных запросов, связанных с этим результатом запроса: SELECT ARRAY_AGG (DISTINCT CONCAT (user_has_bonuses.bonus_id)) as bonus_ids FROM user_has_bonuses WHERE user_has_bonuses.user_id = users.id Этот запрос должен быть определен один раз. И я должен использовать его везде.

3. CONCAT(user_has_bonuses.bonus_id) может быть упрощен до user_has_bonuses.bonus_id

4. Второй array_agg() для меня не имеет смысла. Как это может отличаться от первого массива bonus_ids?

Ответ №1:

Я думаю, вы ищете боковые соединения. Ваш пример слишком продуман, чтобы действительно иметь смысл, но логика:

 select u.id, ub.*, b.*
from users u
cross join lateral (
    select array_agg(distinct ub.bonus_id) bonus_id
    from user_has_bonus ub
    where ub.user_id = u.id
) ub
cross join lateral (
    select ...
    from bonuses b
    where b.bonus_id = any(ub.bonus_id)
) b
  

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

Обратите внимание, что вы хотите использовать any() , а не in проверять, принадлежит ли значение массиву.