LEFT JOIN使用日期列加入最新行

时间:2015-12-01 15:12:32

标签: mysql sql

我正在尝试从LEFT JOIN中选择最新的行而不是主查询。这是我的SQL:

SELECT * 
FROM   messages 
       LEFT JOIN users 
              ON messages.message_to = users.user_id 
                  OR messages.message_user = users.user_id 
       LEFT JOIN message_replies 
              ON messages.message_id = message_replies.message_reply_main 
       LEFT JOIN user_personal_information 
              ON users.user_id = 
                 user_personal_information.user_personal_information_user 

我想从中选择最新的一行:

       LEFT JOIN message_replies 
              ON messages.message_id = message_replies.message_reply_main

我的专栏名为:message_reply_date - 如何使用它来LEFT JOIN最新一行?

message_replies

CREATE TABLE IF NOT EXISTS `message_replies` (
  `message_reply_id` int(11) NOT NULL,
  `message_reply_user` int(11) NOT NULL,
  `message_reply_main` int(11) NOT NULL,
  `message_reply_message` text NOT NULL,
  `message_reply_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `message_reply_read` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我将它用于WHERE子句:

WHERE m.message_user = ? 
OR m.message_to = ? 
  AND m.message_deleted=0 
  AND m.message_permdeleted=0 
GROUP BY mr.message_reply_main 
ORDER BY mr.message_reply_date DESC

4 个答案:

答案 0 :(得分:2)

如果我理解了这个问题,我会这么做:

var tmpGuest:VIG = VIG()

func textViewShouldEndEditing(textView: UITextView) -> Bool {
    let saveTxt:String = (textView.text == "--" ? "" : textView.text)
    //SET SOME tmpGuest VALUES HERE
    return true
}

@IBAction func editInfo(sender: AnyObject) {
    let actionSheetController: UIAlertController = UIAlertController(title: "Are you sure you wish to save?", message: "Changes are permanent.", preferredStyle: .Alert)

    let okAction: UIAlertAction = UIAlertAction(title: "Yes", style: .Default) { action -> Void in
        //SAVE 
        self.setGuest.setRecords(guestMainTmp: self.tmpGuest)
    }
    actionSheetController.addAction(okAction)

    self.presentViewController(actionSheetController, animated: true, completion: nil)        
}

主查询中没有分组,只是在子查询中使用SELECT * FROM messages LEFT JOIN users ON messages.message_to = users.user_id OR messages.message_user = users.user_id LEFT JOIN message_replies ON messages.message_id = message_replies.message_reply_main LEFT JOIN user_personal_information ON users.user_id = user_personal_information.user_personal_information_user WHERE message_replies.message_reply_date = (SELECT MAX(message_reply_date) FROM message_replies WHERE message_reply_main = messages.message_id) /* AND more criterias */ 评估MAX关于message_reply_date本身的WHERE条件。

答案 1 :(得分:0)

有一个"左连接"获取最新消息的方法(以及其他几个消息)。但是与问题的首选连接方法保持一致:

SELECT * 
FROM messages m LEFT JOIN
     users u
     ON m.message_to = u.user_id OR m.message_user = u.user_id LEFT JOIN
     message_replies mr
     ON m.message_id = mr.message_reply_main LEFT JOIN
     user_personal_information upi
     ON u.user_id = upi.user_personal_information_user LEFT JOIN
     message_replies mr2
     ON mr2.message_reply_main = m.message_id AND
        mr2.message_reply_date > mr.message_reply_date
WHERE mr2.message_reply_main IS NULL;

我还添加了表别名,因为它们使查询更容易编写和阅读。

这个想法是再次匹配表格,但仅限于以后的消息。然后,WHERE子句检查是否存在 - 因此它具有最新的。

答案 2 :(得分:0)

放手一搏。

SELECT * 
FROM   messages 
       LEFT JOIN users 
              ON messages.message_to = users.user_id 
                  OR messages.message_user = users.user_id 
       LEFT JOIN (  SELECT  *
                    ,       MAX(message_reply_date) OVER (PARTITION BY message_id) AS most_recent_message_reply_date
                    FROM    message_replies ) message_replies
                                            ON  messages.message_id = message_replies.message_reply_main 
                                            AND message_replies.message_reply_date = message_replies.most_recent_message_reply_date

       LEFT JOIN user_personal_information 
              ON users.user_id = 
                 user_personal_information.user_personal_information_user 

我已将您的直接调用替换为message_replies表,其中Select显示表,并且最大回复日期按message_id分组。然后,我将其添加到联接中以过滤除您要查找的答案之外的所有答案。

快走,任何问题都给我留言,随时乐意为您提供帮助。

答案 3 :(得分:0)

你想要做的是模仿等级&在MSSQL和&amp ;;中看到的分区功能PL / SQL,基本上按日期排名&通过message_reply_main进行分区。

这可以在MySQL中使用外连接&对分区的计数,同时使用<或者>在加入排名标准。这允许您进行标准连接,但也可以使用rank = 1,返回最大的日期。

SELECT * 
FROM   messages 
   LEFT JOIN users 
          ON messages.message_to = users.user_id 
              OR messages.message_user = users.user_id 
   LEFT JOIN (select mri.message_reply_main
              , mri.message_reply_date
              , mri.message_reply_message
              , mri.message_reply_read
              , count(mri2.message_reply_main) + 1 as rank
              FROM message_replies mri
              left join message_replies mri2 on mri.message_reply_date < mri2.message_reply_date 
              and mri.message_reply_main = mri2.message_reply_main
              group by mri.message_reply_main, mri.message_reply_message
                       , mri.message_reply_read, mri.message_reply_date) mr ON messages.message_id = mr.message_reply_man
                                                                            AND mr.rank = 1
   LEFT JOIN user_personal_information 
          ON users.user_id = 
             user_personal_information.user_personal_information_user