我有一个网络应用程序我正在尝试分析和优化,最后一件事就是修复这个慢速运行的功能。我无论如何都不是SQL专家,但是知道在一步SQL查询中执行此操作会比我现在正在执行的操作快得多,具有多个查询,排序和迭代循环。
问题基本上是这样的 - 我想要来自“user”表的数据行,由UserData对象表示,其中给定回合的“bid”表中没有该用户的条目。换句话说,我的数据库中的哪些投标人尚未提交出价。
在SQL伪代码中,这将是
SELECT * FROM users WHERE users.role='BIDDER' AND
users.user_id CANNOT BE FOUND IN bids.user_id WHERE ROUND=?
(显然这不是有效的SQL,但我不太了解SQL,无法将它正确地组合在一起)。
谢谢!
答案 0 :(得分:2)
您可以使用LEFT JOIN执行此操作。 LEFT JOIN在两个表之间创建一个链接,就像INNER JOIN一样,但也包括LEFT表(这里是用户)与正确表没有关联的记录。
这样做,我们现在可以添加一个where子句来指定我们只想要与右表没有关联的记录。
右表和左表由您编写连接的顺序决定。左表是第一部分,右表(这里是出价)在右边部分。
SELECT * FROM users u
LEFT JOIN bids b
ON u.user_id = b.user_id
WHERE u.role='BIDDER' AND
b.bid_id IS NULL
答案 1 :(得分:0)
SELECT u.*
FROM users u
LEFT OUTER JOIN bids b on b.user_id = u.user_id
WHERE u.role = 'BIDDER'
AND b.user_id IS NULL
答案 2 :(得分:0)
您可以使用左连接(由Dave提出)或使用子查询来执行此操作:
select *
from users u
where u.role = 'BIDDER' and not exists (
select *
from bids b
where b.user_id = u.user_id and b.round = ?)
或等效
select *
from users u
where u.role = 'BIDDER' and u.user_id not in (
select b.user_id
from bids b
where b.round = ?)
编辑
如果要使用左连接并且要添加查询参数,则必须将其放在ON子句(而不是WHERE子句)中:
SELECT * FROM users u
LEFT JOIN bids b
ON u.user_id = b.user_id AND b.round = ?
WHERE u.role='BIDDER' AND b.bid_id IS NULL
答案 3 :(得分:0)
SELECT * from users
WHERE users.rol='BIDDER'
AND users.user_id not in (SELECT user_id FROM bids WHERE round =?)
答案 4 :(得分:0)
性能比较的另一种选择。给定您的伪代码,您可能会发现它比左连接更具可读性。
SELECT *
FROM users u
WHERE u.role='BIDDER'
AND NOT EXISTS (
SELECT 1
FROM bids b
WHERE b.round = ?
AND b.user_id = u.user_id
)