8

我有两张桌子。第一个表如下所示:

表:记录

    摆脱| 用户名 | 标题 | 添加时 | 上市
-------------------------------------------------- ------------------
    1 212 示例 2012-06-28 1
    2 217 测试建议 2012-07-05 1
    3 212 另一个 2012-07-02 1
    4 212 未上市 2012-05-02 0
    5 217 成功 2012-04-08 1
    6 238 总是 2012-04-18 1

表:喜欢

    编号 | 用户名 | 摆脱| 喜欢的时候
-------------------------------------------------- ----
    1 212 2 2012-07-06
    2 205 1 2012-06-30
    3 212 5 2012-07-04

在'Records'表中,'rid'被设置为主索引。在“喜欢”表中,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 和 Google 其他地方搜索解决方案所找到的结果。

这些是我试图通过以下方式订购的条件:

  1. 选择的所有记录都必须是公开的 (records.public = 1)。
  2. 如果记录属于用户(在本例中为 212),则按 records.when added 对记录进行排序。
  3. 如果记录不属于用户,但它是用户喜欢的记录,则通过 likes.whenliked 对记录进行排序。
  4. 日期将按从最新到最旧的顺序排列。

返回的查询的最终结果如下所示(请记住,whenliked 不在返回数据中,它只是供参考,因此您可以看到它是如何排序的):

    摆脱| 用户名 | 标题 | 添加时 | 公共 | 喜欢时{不包括}
-------------------------------------------------- ----------------------------------
    2 217 测试建议 2012-07-05 1 2012-07-06
    3 212 另一个 2012-07-02 1
    5 217 成功 2012-04-08 1 2012-06-30
    1 212 示例 2012-06-28 1

希望这是有道理的。随意提问,我会尽我所能澄清。

提前感谢您的时间、考虑和阅读本文。即使没有响应或没有找到解决方案,仍然非常感谢您的时间!:)

4

4 回答 4

4

您订购的字段不必是数据库中的现有字段。您还可以使用您在选择中定义的字段:

SELECT IF(records.userid = ' . $userid . ', records.whenadded, likes.whenliked) as date 

现在您可以按部分顺序使用它:

ORDER BY date DESC

来自MySQL 手册

可以使用 AS alias_name 为 select_expr 指定别名。别名用作表达式的列名,可用于 GROUP BY、ORDER BY 或 HAVING 子句

于 2012-07-06T06:53:15.040 回答
1

我建议将查询分成 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

于 2012-07-06T06:51:11.287 回答
0

这个怎么样:

$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;';

这将首先将按用户记录和按用户喜欢的记录分开,然后按日期分开。

于 2012-07-06T06:56:47.387 回答
0

根据我的评论,这是您应该查看的另一个查询:

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 的文档在这里

这个查询并不是真正意义上的性能。如果您有一个非常大的数据库,则将查询分​​成两部分,以便以全功率使用用户 ID 上的索引,然后再次加入它们可能会更好。

于 2012-07-06T07:23:06.977 回答