我在接受采访时被问到要在白板上做什么,而我的解决方案对于白板的答案来说似乎太复杂了。
我有两个表,一个有id和名称作为表Person,另一个有id,person_id和friend_id作为表朋友。朋友表中的一行表示两个人之间的友谊。我想为" Gina"找到友谊的所有实例。不知道她的身份。
我想出了:
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';
我在白板上思考不好,这不是最佳解决方案。任何人都可以优化这个吗?
为几个朋友制作了一个方便的东西,以后随处可见:
答案 0 :(得分:0)
如果你想要的是将吉娜列为朋友的人的名字,那就可以了。
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 slightly faster比你的{{3}}。根据我的经验,十分之九,尽可能简单地说明查询并让数据库弄清楚是最好的方法。
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')
;
答案 1 :(得分:0)
这有效,但我不确定哪一个更快......你必须进行基准测试......
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