基本上,我有一个包含两个字段的表:[id, other]
,其中存储了用户令牌。我的查询的目标是选择之前未选择的随机用户。选择用户后,它将存储在上面显示的表中。因此,如果杰克随机选择吉姆,杰克不能再选择吉姆,而另一方面,吉姆不能选择杰克。
这就是我想到的:
SELECT * FROM users
WHERE (SELECT * FROM selected WHERE (id=? AND other=?) OR (id=? AND other=?));
嗯,首先我读过使用这样的子查询是非常有用的,我甚至不确定我是否使用了正确的语法,但问题是,我有很多在我的场景中我需要过滤的表格,所以看起来更像是这样。
SELECT * FROM users u
WHERE (SELECT * FROM selected WHERE (id=? AND other=?) OR (id=? AND other=?))
AND (SELECT * FROM other_table WHERE (id=? AND other=?) OR (id=? AND other=?))
AND (SELECT * FROM diff_table WHERE (id=? AND value=?))
AND u.type = 'BASIC'
LIMIT = 1
我觉得这是一种更有效的处理方式。
请注意:如果用户ID出现在任何嵌套查询中,我根本不想要返回一行。返回" null"还不够。我有OR
子句的原因是因为用户的ID可以存储在id
或other
字段中,因此我们需要检查两者。
我正在使用Postgre 9.5.3,但我添加了MySQL标签,因为代码主要是向后兼容的,只接受Fancy Postgre解决方案(如果有的话)
答案 0 :(得分:1)
使用针对错过的联接筛选的外部联接:
SELECT * FROM users u
LEFT JOIN selected s on u.id in (s.id, s.other) and ? in (s.id, s.other)
WHERE u.id != ?
AND s.id IN NULL
LIMIT 1
答案 1 :(得分:1)
您可以将联接保留到另一个表,该表生成没有找到记录的空值:
Select u.* from users u
left selected s on s.id = u.id or s.other = u.other
where s.id is null
联接或联接是不同的,但应该有效。例子有点傻......但只要你理解逻辑。左连接第一个表到第二个表,其中第二个表列不为空意味着找到了至少一个匹配连接条件的记录。其中第二个表列为null表示未找到记录。
你是对的......尽可能避免where field =(select statement)逻辑,那里表现不佳。