好的,所以我正在研究一个MySQL的搜索功能但是遇到了一些我似乎无法解决的问题。我正在尝试制作一个脚本来搜索用户朋友,并返回得分更高的朋友。这就是我到目前为止所做的:
SELECT id, first_name, last_name, image_id FROM users
WHERE id IN (
SELECT receiver AS friend FROM friends WHERE initiator = :me AND status = :status
UNION
SELECT initiator AS friend FROM friends WHERE receiver = :me AND status = :status
) ORDER BY score AND concat(first_name, ' ', last_name) LIKE '%test query%';
现在一切正常,直到我尝试按分数订购朋友。任何人都可以锻炼如何按分数订购朋友吗?如果你需要我澄清什么,只要问。
我有以下两张表。
用户表:
朋友表:
根据要求,这里有一些示例数据:
例如,我有三个用户:
ID: 1, first_name: Michael, last_name: Sample
ID: 2, first_name: John, last_name: Citizen
ID: 3, first_name: Caitlin, last_name: Wired
下面的第一个条目将让迈克尔和凯特琳成为朋友,表明迈克尔发起了一个朋友请求而凯特琳(接收者)接受了它。 (因此1)的状态他们的基本分数是10.第二个条目显示John也是Caitlin的朋友(由Caitlin发起)但得分更高。
ID: 10000, initiator: 1, receiver: 3, status: 1, score: 10
ID: 10001, initiator: 3, receiver: 2, status: 1, score: 20
所以在这个样本数据的情况下。如果Caitlin是用户搜索她的朋友,它应该显示John而不是Michael。
答案 0 :(得分:3)
外部语句仅从users
列中选择,该列没有score
列。几乎所有使用子选择的语句都可以(并且应该)使用连接重写。在这种特殊情况下,它将允许在子句中使用所有friends
字段。
SELECT u.id, u.first_name, u.last_name, u.image_id
FROM users AS u
JOIN friends AS f
ON ...
子选择的WHERE
子句中使用的表达式成为连接条件。联盟在某种意义上等同于OR
(两者基本上都是conjunctions)。
ON (u.id = f.receiver AND f.initiator=:me AND status=:status)
OR (u.id = f.initiator AND f.receiver=:me AND status=:status)
声明的其余部分几乎保持不变。
WHERE concat(first_name, ' ', last_name) LIKE '%test query%'
ORDER BY score
;
总之,那是:
SELECT u.id, u.first_name, u.last_name, u.image_id
FROM users AS u
JOIN friends AS f
ON (u.id = f.receiver AND f.initiator=:me AND status=:status)
OR (u.id = f.initiator AND f.receiver=:me AND status=:status)
WHERE concat(first_name, ' ', last_name) LIKE '%test query%'
ORDER BY score
;
请注意,这是未经测试的,只是在我的头顶。
答案 1 :(得分:0)
例如,使用union
订购SELECT T.* /*ANY COLUMN SET WITH(OUT) SCORE */ FROM(
SELECT SCORE,.... FROM ANOTHERTABLE WHERE .....
UNION SELECT SCORE,.... FROM ANOTHERTABLE WHERE ...
) T
ORDER BY SCORE
更好的重写
SELECT id, first_name, last_name, image_id FROM users
JOIN (
SELECT score,receiver AS friend FROM friends WHERE initiator = :me AND status = :status
UNION
SELECT score,initiator AS friend FROM friends WHERE receiver = :me AND status = :status
) t ON T.ID = users.id ORDER BY score AND concat(first_name, ' ', last_name) LIKE '%test query%';