我有两个表。第一张表如下:
表:记录
rid|user-id|title |添加时|public--------------------------------------------------------------------1 212示例2012-06-28 12 217试验记录2012-07-05 13 212另一个2012-07-02 14 212非上市2012-05-02 05 217成功2012-04-08 16 238永远2012-04-18 1
表:喜欢
id |用户id | rid |点赞时------------------------------------------------------1 212 2 2012-07-062 205 1 2012-06-303 212 5 2012-07-04
在"Records"表中,"rid"被设置为主索引。在"Likes"表中,id被设置为主要索引。
我在用PHP。PHP将为MySQL提供一个值作为参考。我想要一个MySQL查询,它将执行以下操作:
伪代码:
$userid = 212;
$SQL = 'SELECT DISTINCT records.*
FROM records,likes
WHERE (records.userid = ' . $userid .
' AND records.public = 1)
OR (records.id = likes.rid AND likes.userid = ' . $userid .
' AND records.public = 1)
ORDER BY likes.whenliked DESC, records.whenadded DESC
LIMIT 50;';
看看我刚才提供的$SQL查询。这是我尝试开发我想要的查询,但它没有达到我想要的目的;它非常接近,但它仍然订购错误。这个查询是我自己开发的,然后是基于我在StackFlow和谷歌其他地方搜索解决方案的结果。
这些是我试图订购的条件:
- 所选的所有记录都必须是公共的(records.public=1)
- 如果记录属于用户(在本例中为212),则在添加时按记录对记录进行排序
- 如果该记录不属于用户,但它是用户喜欢的记录,则按点赞对记录进行排序
- 日期将从最新到最老排序
返回的查询的最终结果是这样的(请记住,当liked不在返回数据中时,它只是供参考,这样你就可以看到它是如何排序的):
rid|user-id|title |whengadd|public|whenwicked{not incl}------------------------------------------------------------------------------------2 217试验记录2012-07-05 1 2012-07-063 212另一个2012-07-02 15 217成功2012-04-08 1 2012-06-301 212示例2012-06-28 1
希望这是有道理的。请随意提问,我会尽我所能澄清。
提前感谢您的时间、考虑和阅读。即使没有回应或没有找到解决方案,我们仍然非常感谢您的时间!:)
排序依据的字段不必是数据库中的现有字段。您也可以使用您在选择中定义的字段:
SELECT IF(records.userid = ' . $userid . ', records.whenadded, likes.whenliked) as date
现在您可以按部件顺序使用它:
ORDER BY date DESC
来自MySQL手册:
select_expr可以使用AS alias_name获得别名。别名用作表达式的列名,可以在GROUP BY、ORDER BY或HAVING子句中使用
我建议将查询拆分为2个查询,并使用UNION。
SELECT * FROM(
(SELECT records.rid, records.userid,records.title, records.whenadded as adate
FROM records,likes
WHERE records.userid = $userid AND records.public = 1 )
UNION
(SELECT records.rid, records.userid,records.title, likes.whenliked as adate
FROM records,likes
WHERE records.rid = likes.rid AND likes.userid = $userid
AND records.public = 1)
)t ORDER BY adate DESC
编辑时间:请参阅http://sqlfiddle.com/#!2/9a877/4
这个怎么样:
$userid = 212;
$SQL = 'SELECT DISTINCT records.*
FROM records,likes
WHERE (records.userid = ' . $userid .
' AND records.public = 1)
OR (records.id = likes.rid AND likes.userid = ' . $userid .
' AND records.public = 1)
ORDER BY records.userid, likes.whenliked DESC, records.whenadded DESC
LIMIT 50;';
这将按用户和点赞先按用户分隔记录,然后按日期分隔。
根据我的评论,这里有另一个您应该查看的查询:
SELECT
records.*
FROM records
LEFT JOIN likes ON records.rid = likes.rid
WHERE records.public = 1
AND COALESCE(likes.userid, records.userid) = $userid
ORDER BY COALESCE(likes.whenliked, records.whenadded) DESC;
它假设你不会喜欢一张唱片超过一次,并获得了奇怪的DISTINCT。
COALESCE的文档在这里。
这个查询实际上并不是性能方面的。如果你有一个非常大的数据库,那么将查询一分为二,以便充分利用userid上的索引,然后再次加入它们可能会更好。