我有两张桌子:
conversation_participants
id | conversation_id | user_id
int(11) | int(11) | int(11)
用户
id | username | ....
int(11) | varchar(20)| ....
我正在尝试选择在用户名中具有特定字符串的所有用户,这些用户不是特定对话中的参与者。目前我有两个SQL查询:
SELECT user_id FROM conversation_participants WHERE conversation_id=?
和
SELECT id, username from users WHERE username LIKE '%%%{$_GET['q']}%%' ORDER BY id DESC LIMIT 10
并从第二个查询中删除与第一个查询中的user_id相同的所有结果。有没有办法将这两个查询合并为一个?
提前谢谢
答案 0 :(得分:2)
SELECT id, username from users
WHERE username LIKE '%%%{$_GET['q']}%%'
and username not in
(
SELECT user_id FROM conversation_participants
WHERE conversation_id=users.conversation_id
)
ORDER BY id DESC LIMIT 10
不要构建连接字符串的sql语句。您应该使用某种实用方法来清理您的输入。您的陈述容易发生SQL注入攻击。
PHP有几个功能。查看mysql_real_escape_string
答案 1 :(得分:1)
除了上面的答案,我还要补充一点,你不应该在你的查询中直接使用$ _GET(etc)参数而不检查SQL注入。
答案 2 :(得分:1)
您可以使用LEFT JOIN和IS NULL
执行此操作SELECT
u.id,
u.username
from
users u
LEFT JOIN
conversation_participants cp
ON (u.id=cp.user_id AND cp.conversation_id=?)
WHERE
username LIKE '%%%{$_GET['q']}%%' AND
cp.user_id IS NULL
ORDER BY id DESC LIMIT 10
我认为这比使用NOT IN()和子查询出于性能原因更为理想。
答案 3 :(得分:0)
您也可以使用JOIN,这可能会更快一些。
SELECT u.id, u.username from users u LEFT JOIN conversation_participants c ON c.user_id = u.id WHERE u.username LIKE '%%%{$_GET['q']}%%' AND c.conversation_id != ? ORDER BY u.id DESC LIMIT 10
答案 4 :(得分:0)
除了上述答案,您还可以删除表conversation_participants中的“id”字段,并将2个字段conversation_id和user_id定义为主键。