2013-11-22 65 views
0

我有一个web应用程序我试图分析和优化,最后一件事之一是修复这个慢运行功能。我不是任何SQL专家,但是知道在一步SQL查询中执行此操作的速度要比我现在执行的操作要快得多,包括多个查询,排序和循环遍历。SELECT语句跨2表

问题基本上是这样的 - 我想从UserData对象表示的“用户”表中的数据行,在给定一轮的“出价”表中没有该用户的条目。换句话说,我的数据库中的哪些出价者尚未提交出价。

在SQL伪代码,这将是

SELECT * FROM users WHERE users.role='BIDDER' AND 
users.user_id CANNOT BE FOUND IN bids.user_id WHERE ROUND=? 

(显然,这不是有效的SQL,但我不知道SQL足够好,把它连同正常)。

谢谢!

回答

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 
+0

唯一剩下的就是添加ROUND =? ON条款 – Fabian

+0

当然费边!他的问题的这一部分并不清楚,所以为了清晰起见,我将其删除了! – Dave

+0

呵呵,是的,这个问题确实不是很清楚;)但是对于原来的海报:请把它放到ON子句中,它不会在WHERE子句中起作用 – Fabian

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 
0
SELECT * from users 
WHERE users.rol='BIDDER' 
AND users.user_id not in (SELECT user_id FROM bids WHERE round =?) 
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 
)