在一次面试中,我被问到要在白板上做这件事,而我的解决方案似乎太复杂了,无法在白板上回答。
我有两个表,一个具有id和名称作为表Person,另一个具有id、person_id和friend_id作为表Friend。Friend表中的一行表示两个人之间的友谊。我想找出“吉娜”在不知道她的身份的情况下的所有友谊实例。
我想出了:
SELECT DISTINCT name FROM
(SELECT name1 AS name FROM
(SELECT p1.name AS name1, p2.name AS name2 FROM friend f INNER JOIN person p1 ON f.person_id = p1.id INNER JOIN person p2 ON f.friend_id = p2.id WHERE p2.name LIKE 'Gina' OR p1.name LIKE 'Gina') AS group1
UNION ALL
SELECT name2 AS name FROM
(SELECT p1.name AS name1, p2.name AS name2 FROM friend f INNER JOIN person p1 ON f.person_id = p1.id INNER JOIN person p2 ON f.friend_id = p2.id WHERE p2.name LIKE 'Gina' OR p1.name LIKE 'Gina') AS group2)
AS combo WHERE name <> 'Gina';我不认为白板很好,这不是最好的解决方案。有没有人能优化这一点?
之后给几个朋友弄了个sqlfiddle:
http://sqlfiddle.com/#!2/9d10b/16
发布于 2014-04-14 06:06:32
如果你想要的是将吉娜列为好友的人的名字,这个就行了。
SELECT person.name
FROM person
JOIN friend on friend.person_id = person.id
WHERE friend.friend_id = (SELECT id FROM person WHERE name = 'Gina')
;虽然只有三个人,但你不能真正测试对立面。更好的测试是添加一个不应该出现在结果集中的第四个人。
更新
根据更新后的模式,这将同时获得Gina的朋友和将Gina作为朋友的人。It runs at least as fast or faster比你的好。根据我的经验,十次中有九次,尽可能简单地说明查询并让数据库找出它是最好的方法。
SELECT person.name
FROM friend
JOIN person ON person.id = friend.person_id
WHERE friend.friend_id = (SELECT id FROM person WHERE name = 'Gina')
UNION
SELECT person.name
FROM friend
JOIN person ON person.id = friend.friend_id
WHERE friend.person_id = (SELECT id FROM person WHERE name = 'Gina')
;发布于 2014-04-14 06:36:04
这是可行的,但我不确定哪个更快……你必须进行基准测试...
SET @gina_id=(SELECT id FROM person WHERE name = 'Gina');
SELECT DISTINCT person.name
FROM person
JOIN friend on (friend.person_id = person.id or friend.friend_id=person.id)
WHERE (friend.friend_id = @gina_id
OR friend.person_id = @gina_id)
AND person.id != @gina_id这就是问题所在:http://sqlfiddle.com/#!2/962db/3
https://stackoverflow.com/questions/23048852
复制相似问题