【问题标题】:Idea for writing a mysql query编写mysql查询的想法
【发布时间】:2013-10-15 13:58:50
【问题描述】:

我有一个名为 wp_bp_activity 的表,其中包含许多列,我认为我应该使用其中的 4 个列来解决这个问题:idtypeitem_iddate_recorded

1 - 当有人发布新活动时,typeactivity_updateitem_id0

2 - 当有人对某项活动发表新评论时,其typeactivity_comment 并且item_idid 列中存在的活动ID

3 - 在两者中,date_recorded 是插入数据的日期。

表中还有更多types。

但我只想获取最近有人回复的typeactivity_update 的行是新的(我认为基于date_recorded

我试过的是:

SELECT  a.*, b.*
FROM wp_bp_activity as a, wp_bp_activity as b
WHERE
  ((b.type = 'activity_update') OR (b.type = 'activity_comment' AND b.item_id = a.id))
order by cast(a.date_recorded as datetime) desc
limit 0,20

执行时间过长,以内存不足错误结束。

感谢任何有关此类查询的帮助。

更新 #1

                        wp_bp_activity table

    id              type             item_id         date_recorded
|---------|-----------------------|-----------|--------------------------
|  12081  |   activity_comment    |   12079   |    2013-10-18 07:27:01
|---------|-----------------------|-----------|--------------------------
|  12080  |   activity_update     |     0     |    2013-10-18 07:26:40
|---------|-----------------------|-----------|--------------------------
|  12079  |   activity_update     |     0     |    2013-10-17 05:15:43

我想从这个表中的哪些行是这些 id 按此顺序排列:

12079
12080

我不想得到的东西:

activity_comment 类型

应按什么顺序获取行?

如您所见,activity_comment 类型的行有一个item_id,其值为12079。所以12079是最近有人评论的最新活动,12080没有cmets,只是发布了。所以我两者都想要,但顺序如下:

12079
12080

【问题讨论】:

  • 请revo,看看我的更新... :)
  • 我的主要问题是您是否为表格添加了体面的索引? :)

标签: mysql sql wordpress


【解决方案1】:

我假设您正在寻找“最近的条目”(WHERE type = 'activity_update' AND date_recorded > [threshold])和“有最近回复的条目,无论条目的年龄如何”(WHERE reply.type = 'activity_comment' AND reply.date_recorded > [threshold])。

第一组很简单:

SELECT entries.*
FROM activity AS entries
WHERE type = 'activity_update' AND date_recorded > [threshold]

第二组就不太明显了:

SELECT entries.*
FROM activity AS entries
JOIN activity AS replies
    ON replies.item_id = entries.id
    AND replies.type = 'activity_comment'
WHERE
    entries.type = 'activity_update'
    AND replies.date_recorded > [threshold]

把它们放在一起:

SELECT entries.*
FROM activity AS entries
LEFT JOIN activity AS replies -- LEFT JOIN, because an INNER JOIN would filter out entries without any reply
    ON  replies.item_id = entries.id
    AND replies.type = 'activity_comment'
WHERE
    entries.type = 'activity_update'
    AND (
        entries.date_recorded > [threshold]
        OR replies.date_recorded > [threshold] -- evaluates as FALSE if replies.date_recorded is NULL
    )
ORDER BY IFNULL(replies.date_recorded, entries.date_recorded) -- replies if not null, entries otherwise

我并不为我表现不佳的ORDER BY 子句感到自豪,我希望有人能提出更好的想法

【讨论】:

  • 有效!!但问题是结果有重复的行,如果我使用distinct entries.* 结果会有所不同!
  • 最后只需将 order by 更改为:GROUP BY entries.id ORDER BY IFNULL(max(replies.date_recorded), entries.date_recorded) desc
  • @TsanyoTsanev 我以前使用过该分组,但这并没有解决它。但是您的 ORDER BY 子句完成了工作!谢谢。
【解决方案2】:

你应该再添加一个字段

id, type, item_id, commented_on, date_recorded

::->> commented_on 将证明 item_id cmets 在 commented_on 上,这里是 12079 cmets 在 12080 上,所以你很容易得到你想要的

所以你的结构应该是这样的:

   id             type            commented_on   item_id         date_recorded
|---------|-----------------------|-----------|-----------|--------------------------
|  12081  |   activity_comment    |   12080   |   12079   |    2013-10-18 07:27:01
|---------|-----------------------|-----------|-----------|--------------------------
|  12080  |   activity_update     |     0     |     0     |    2013-10-18 07:26:40
|---------|-----------------------|-----------|-----------|--------------------------
|  12079  |   activity_update     |     0     |     0     |    2013-10-17 05:15:43

【讨论】:

  • 我正在使用 buddypress,所以我无法进行硬编码。还是谢谢!
  • 您不需要任何硬编码,您只需从 phpmyadmin 创建一个字段,只需一分钟。并且比它更容易触发查询。
  • 向该字段插入值不需要硬编码?!
  • 不,你只需要一个编辑插入查询,一点都不难
【解决方案3】:

也许我错过了一些巨大的东西,但有什么问题?:

SELECT *
FROM `wp_bp_activity`
WHERE `type`='activity_update'
ORDER BY `date_recorded` ASC
LIMIT 0, 20;

【讨论】:

    【解决方案4】:

    您在 OR 子句中有您的 JOIN 条件。这是一个很好的例子,说明了为什么你不应该使用这种语法。

    SELECT  a.*, b.*
    FROM wp_bp_activity as a JOIN wp_bp_activity as b ON b.item_id = a.id
    WHERE
      ((b.type = 'activity_update') OR (b.type = 'activity_comment'))
    order by cast(a.date_recorded as datetime) desc
    limit 0,20
    

    【讨论】:

    • 在您的查询中,所有结果都必须有b.item = a.id,但是在我的查询中,b.item = a.id 应该只等于b.type = 'activity_comment'
    • 我需要根据最近获得评论或发布的活动来排序结果。但是通过这种方式,它们是按 id 排序的!
    • 安迪请看更新。我在某种程度上使我的解释更容易了。
    猜你喜欢
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 2013-04-21
    • 1970-01-01
    • 2014-12-25
    • 2023-03-24
    • 1970-01-01
    • 2011-09-13
    相关资源
    最近更新 更多