【问题标题】:MySql Sort by Date in JOIN QueryMySql 在 JOIN 查询中按日期排序
【发布时间】:2014-01-11 18:09:51
【问题描述】:

我正在尝试显示来自两个表的项目的新闻提要。

Table 1: News - Id / Title / Date
Table 2: Shared_News - Id / News_Id / Date

来自Shared_NewsNews_Id 实际上是来自News 表的Id。现在的场景...

我的新闻提要必须显示新闻表中的项目以及 Shared_News 项目。 Shared_News 项目将根据共享日期与 News 项目合并。

让我们举个例子,我们从News 表中显示 Id 的 2、4、6、8,按日期排序,如下所示

8
6
4
2

现在让支持某人在文章 8 发布后的某个日期与用户分享了 News 项目 5,它被输入到 Shared_News 表中。我希望显示以下顺序

5
8
6
4
2 

现在如果在第 4 项发布后共享第 1 项,则顺序应如下所示

5
8
6
1
4
2

有人可以帮助我,因为我正在做的左连接不起作用。下面是我的代码/我正在使用 Codeigniter 框架。

$stories_finalized 下面是新闻 ID 和共享新闻 ID 的合并列表。

$select =   array(
    'users.name',
    'story.id as story_id',
    'story.date',
    'story.title',
    'story.user_id',
    'share.date as shared_story_date'
);
$where  =   array('story.show' => 1);
$this->db
        ->select($select)
        ->where_in('story.id', $stories_finalized)
        ->join('users', 'users.id = story.user_id')
        ->join('share', 'share.story_id = story.id', 'LEFT')
        ->where($where)
        ->order_by('share.date, story.date', 'DESC')
        ->limit(STORY_QUERY_LIMIT, $from);

Story Table 中存储的数据如下所示

59 | This is an example story | 2013-09-20
45 | This is the title of the shared story | 2013-08-12

Share 表中存储的数据如下

1 | 45 | 2013-12-24

最后,我希望数据如下所示

45 | This is the title of the shared story | 2013-08-12
59 | This is an example story | 2013-09-20

提前非常感谢!

【问题讨论】:

  • 我们可以有一些实际数据而不仅仅是 ids 吗?两张桌子?
  • @PeterRing 是的,我们绝对可以获取数据。
  • 我删除了 SQL Server 标签,因为这是关于 MySQL 的,并添加了 codeigniter,因为它是关于 Code Igniter。
  • @foxybagga,PeterRing 的意思是,你能向我们展示数据吗?我们不知道它是如何存储的。
  • shared_story_date中存储的日期是否为空?

标签: php mysql sql codeigniter join


【解决方案1】:

您正在查找每条新闻的最后分享日期(如果有)。所以找到这些,将它们与新闻一起加入,然后按共享日期(如果有)排序,否则按发布日期排序:

select news.title, news.date_published, last_shared.share_date
from news
left outer join
(
  select news_id, max(date_shared) as share_date
  from shared_news
  group by news_id
) last_shared on (last_shared.news_id = news.id)
order by coalesce(last_shared.share_date, news.date_published) desc;

顺便说一句:不要将列称为“日期”,因为这是一个 SQL 词。

【讨论】:

  • date is keyword 绝对正确。这可能是问题的原因
  • @thorsten - 我不知道该怎么做 - 这很困难,用户的加入正在扼杀它。
  • @thorsten-kettner - 我想不通。你能帮我一些建议吗...我已经粘贴在我正在使用的下面...
  • 抱歉这么晚才回来。请查看我的 cmets 到您发布的内容。
【解决方案2】:

这就是我最终要做的。我使用 Codeigniter。

$this->db->select('users.name, story.date, story.title, IFNULL(share.date, story.date) as sort_date', FALSE)
->where_in('story.id', $stories_finalized)
->where(array(
     'story.show' => 1
))
->join('users', 'users.id = story.user_id', 'INNER')
->join('share', 'share.story_id = story.id', 'LEFT OUTER')
->group_by('story.id')
->order_by('sort_date', 'DESC');    

感谢 Thorsten 指出重复的 story_id 并感谢傅满洲博士指出接近它的方法。

【讨论】:

  • 要么让 users.name 成为 GROUP BY 子句的一部分,要么使用聚合函数(例如 MIN 或 MAX)访问它。
  • 我不知道 Codeigniter 如何处理 FROM 子句中的子选择。你能简单地写“->join('(select ... from ...)',...”而不是“->join('share',...”吗?否则我会建议进行子查询一个名为“latest_share”的视图并访问该视图“->join('latest_share', ...”而不是表。
  • @ThorstenKettner 非常感谢您的评论。我通过添加 ->join('share', 'share.story_id = story.id AND share.user_id = '.$user_id, 'LEFT OUTER') 解决了这个问题。主要问题是在此搜索 - 我可以通过 story.title 成功搜索,但我无法通过 user.name 搜索,这是我想做的事情。搜索一个或两个。
  • 对不起,我不明白。您选择故事并加入作者(用户),即每个故事一个用户 - 到目前为止我的理解。然后你加入故事的所有分享,这会导致每个故事产生许多记录,而不是一个(这就是为什么我告诉你找到每个故事的最新分享并使用它)。现在你告诉我你通过将分享用户限制为 .$user_id 来减少分享(这是谁?)是否可以保证一个用户每个故事只能分享一个?
  • 现在您要搜索。你说的是where子句吗?您加入故事和用户,因此您可以在 where 子句中使用两个表的所有字段。那应该不是问题。所以我想知道是什么阻碍了你。我的建议:想清楚你想选择什么:故事的哪个份额?特定用户的分享或用户的故事?当你想通了,然后使用 SQL 看看你是否得到了你想要的。一旦这工作,编写相应的 Codeigniter 代码。祝你好运!
【解决方案3】:

试试这个查询:

SELECT users.*, story.*, IFNULL(share.`date`, story.`date`) AS sort_date FROM 
users INNER JOIN story ON users.id = story.user_id
LEFT JOIN share ON share.story_id = story.id
WHERE story.id IN (....)
ORDER BY sort_date DESC

我无法帮助将其翻译成 codeigniter 语法...

【讨论】:

  • 应该做然后回来
  • 奇怪,它不应该。这不会为您提供按最后共享日期排序的故事,而是所有共享(即一个故事多次)。这不是你问的。但是好吧,也许这就是你的意思:-)
  • 它没有 - 它的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-30
  • 2015-05-08
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多