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,以便不再出现“子查询列过多”错误?
答案 0 :(得分:1)
您的子查询必须具有比您要比较的外部值准确的列数。
例如,您可以使用单列:
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
答案 1 :(得分:1)
您的查询有点难以理解。我认为这是您真正想要的逻辑:
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
);
这将返回没有租金的用户/船组合。
答案 2 :(得分:0)
您只需要在子查询中删除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子句无论如何都会否定LEFT JOIN来出租,因此可以简化为:
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,但是我没有足够的信息来确定您想要什么。