БД возвращает 0 записей из-за подзапроса (PostgreSQL)

У меня есть 2 таблицы:

  1. products - содержит 2 столбца: id, name
  2. products_to_products - нужна для отношения многие ко многим, в ней сохраняются похожие товары. Содержит столбцы: id, product1_id, product2_id

Мне нужно с помощью одного запроса к БД получить все товары, которые есть в БД, а так же похожие товары. Я делаю это так:

SELECT 
    products.*,
    (SELECT array_agg(products_to_products.product2_id)
        FROM products_to_products
        WHERE products.id = products_to_products.product1_id) as similar_products
FROM products, products_to_products
GROUP BY products.id
ORDER BY id ASC;

Это отлично работает, если в таблице products_to_products есть хотя бы одна запись (неважно какая). Но как только в таблице products_to_products становится 0 записей, то этот запрос возвращает 0 продуктов (хотя в таблице products записи есть). Почему так происходит и как мне это исправить?


Ответы (1 шт):

Автор решения: Ainar-G

Крайне не рекомендую использовать запятую во FROM. Потому что это скрытый CROSS JOIN с парой отличий, и такие вещи не должны быть настолько незаметными. Ваша же изначальная задача решается как-то так:

WITH similar_products AS (
  SELECT products_to_products.product1_id AS id
       , ARRAY_AGG(products_to_products.product2_id) AS similar
    FROM products_to_products
   GROUP BY products_to_products.product1_id
)
SELECT products.*
     , similar_products.similar
  FROM products
        LEFT JOIN similar_products
       USING (id)
 ORDER BY products.id DESC
;
→ Ссылка