PostgreSQL: подзапрос имеет слишком много столбцов при попытке добавить фильтры - PullRequest
0 голосов
/ 28 июня 2019
SELECT users.id as user_id, boats.id as boat_id
FROM users
CROSS JOIN boats
WHERE users.id NOT IN 
   (SELECT users.id as user_id, boats.id as boat_id FROM users 
    LEFT JOIN rentals ON (users.id=rentals.user_id)
    LEFT JOIN boats on (boats.id=rentals.boat_id)
    WHERE users.id=rentals.user_id)
ORDER BY users.id

Как я могу разделить эти JOINы, чтобы я больше не получал ошибку "подзапрос имеет слишком много столбцов"?

Ответы [ 3 ]

1 голос
/ 28 июня 2019

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

SELECT u.id as user_id, b.id as boat_id
FROM users u CROSS JOIN
     boats b
WHERE not exists (SELECT 1
                  FROM rentals r
                  WHERE r.user_id = u.id AND
                        r.boat_id = b.id
                 );

Возвращает комбинации пользователя и лодки, у которых нет проката.

1 голос
/ 28 июня 2019

Ваш подзапрос должен иметь точное число столбцов, с которыми сравниваются внешние значения.

Например, вы можете использовать столбец single :

SELECT users.id as user_id, boats.id as boat_id
FROM users
CROSS JOIN boats
WHERE users.id NOT IN 
   (SELECT users.id FROM users -- fixed here
    LEFT JOIN rentals ON (users.id=rentals.user_id)
    LEFT JOIN boats on (boats.id=rentals.boat_id)
    WHERE users.id=rentals.user_id)
ORDER BY users.id

или использовать кортеж с двумя столбцами:

SELECT users.id as user_id, boats.id as boat_id
FROM users
CROSS JOIN boats
WHERE (users.id, boats.id) NOT IN -- fixed here
   (SELECT users.id as user_id, boats.id as boat_id FROM users 
    LEFT JOIN rentals ON (users.id=rentals.user_id)
    LEFT JOIN boats on (boats.id=rentals.boat_id)
    WHERE users.id=rentals.user_id)
ORDER BY users.id
0 голосов
/ 28 июня 2019

Вы просто оставляете boat.id в подзапросе:

SELECT users.id as user_id, boats.id as boat_id
FROM users
CROSS JOIN boats
WHERE users.id NOT IN 
   (SELECT users.id as user_id
    FROM users 
    LEFT JOIN rentals ON (users.id=rentals.user_id)
    LEFT JOIN boats on (boats.id=rentals.boat_id)
    WHERE users.id=rentals.user_id)
ORDER BY users.id

Тем не менее, нет причин добавлять LEFT JOIN к лодкам в подзапросе, поскольку он не используется. Кроме того, предложение WHERE в любом случае сводит на нет левое соединение с арендной платой, поэтому это можно упростить до:

SELECT users.id as user_id, boats.id as boat_id
FROM users
CROSS JOIN boats
WHERE not exists (
    SELECT 1
    FROM rentals 
    WHERE rentals.user_id = users.id
);

Я также немного скептически отношусь к тому, что вам нужно CROSS JOIN, но у меня недостаточно информации, чтобы точно определить, что вы хотите.

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