简体   繁体   English

如何有效地从2个mysql表中选择唯一的行/记录数据并返回一个按时间戳排序的合并结果?

[英]How do I efficiently select unique row/record data from 2 mysql tables and return one merged result, ordered by timestamp?

Stack: 堆:

I'm trying to turn my website's user profile into more of a feed style page. 我正在尝试将网站的用户个人资料转变为供稿样式页面。 Currently the profile shows some user stats at the top, then the last 10 comments a user submitted (ordered by timestamp descending), then the last 10 posts they have submitted. 当前,配置文件在顶部显示一些用户统计信息,然后是用户提交的最后10条评论(按时间戳降序排列),然后是他们提交的最后10条帖子。

What I want to do instead, is have the last 20 "actions" (either comment or post submission) listed in order of the timestamp (so the comments and submissions will be merged together in the list instead of having 2 seperate lists). 我要做的是按时间戳顺序列出最后20个“操作”(评论或发布后)(因此评论和提交将合并到列表中,而不是2个单独的列表)。 You know, like a "feed." 你知道,就像“饲料”。

The issue is that the comments are pulled from a comments table, and the submissions are pulled from a "submissions" table. 问题在于,注释是从注释表中提取的,而提交是从“提交”表中提取的。

I've solved it in a pretty inefficient way by using a union query to select "comment_id/submission_id", "field the identifies record as a comment or a submission", "timestamp" from both tables. 通过使用联合查询从两个表中选择“ comment_id / submission_id”,“将标识记录作为注释或提交字段”,“时间戳”,我以一种非常低效的方式解决了该问题。

This gives me a result that tells my the entity id, as well as defines the entity as a comment or a post, by which I can then shoot off another query in a while mysql_fetch_array statement to get the full comment or submission data. 这给了我一个告诉我实体ID的结果,以及将实体定义为注释或帖子,然后我可以通过它在mysql_fetch_array语句中启动另一个查询以获取完整的注释或提交数据。

This just seems really dirty to me, since I'm basically querying the tables, finding the rows/records that I need (but ignoring the actual data I need since the different table's columns don't match up as I believe to be necessary for a union query), then going back for the data I ignored the first time with individual queries in a while statement... 这对我来说似乎真的很肮脏,因为我基本上是在查询表,查找所需的行/记录(但忽略了我需要的实际数据,因为不同的表的列不匹配,因为我认为这是必要的)联合查询),然后返回我第一次使用while语句中的单个查询忽略的数据...

Is there a better way to do this that I don't know of? 有我不知道的更好的方法吗?

Additional notes: 补充笔记:


Example sql I'm currently using to build the initial result I spoke of above: 我目前用于构建上面提到的初始结果的示例sql:

select comment_id, datatype, timestamp from comments where userid=3
union all
select content_id, datatype, timestamp from submissions where userid=3
ORDER BY timestamp DESC

Returns a result like this: 返回如下结果:

commentid  datatype      timestamp 
5201       post          2012-03-27 20:30:40
43761      comment       2012-03-26 21:00:19
43759      comment       2012-03-26 20:59:47
5033       post          2012-03-26 20:57:36
43755      comment       2012-03-26 20:54:57
43745      comment       2012-03-26 16:32:24

Pseudocode I can then use to print out the information onto the profile page: 然后,我可以使用伪代码将信息打印到个人资料页面上:

while ($content_array = mysql_fetch_array($abovequery)){ 而($ content_array = mysql_fetch_array($ abovequery)){

Individual select query fetching the full row by from either comment table or submission table by id depending on $content_array['datatype']; 单独的选择查询根据$ content_array ['datatype']从注释表或提交表中按ID提取整行;

echo out relevant data from individual select query onto profile screen in a pretty way; 将个人选择查询中的相关数据以漂亮的方式回显到个人资料屏幕上;

} }

Surely this can be done better? 当然可以做得更好吗?

If you are unable to coerce the columns of the two full queries in such a way that it can all be returned in the UNION then you could join the union result to the comments and submissions tables. 如果无法以可以在UNION中全部返回的方式强制两个完整查询的列,则可以将联合结果加入注释和提交表。

SELECT records.datatype, comments.*, submissions.*
FROM (
    (
        SELECT comment_id, datatype
        FROM comments
        WHERE userid=3
        ORDER BY timestamp DESC
        LIMIT 20
    ) UNION ALL (
        SELECT content_id, datatype
        FROM submissions
        WHERE userid=3
        ORDER BY timestamp DESC
        LIMIT 20
    )
    ORDER BY timestamp DESC
    LIMIT 20
) AS records
LEFT JOIN comments
    ON records.comment_id = comments.comment_id
    AND records.datatype = 'comment'
LEFT JOIN submissions
    ON records.comment_id = submissions.content_id
    AND records.datatype = 'post'

Alternatively, you could run the two innermost selects with all required fields and then order the final result in PHP. 另外,您可以使用所有必填字段运行两个最里面的选择,然后在PHP中排序最终结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM