我的SQL查询用于查找具有匹配主键的max< = date

时间:2012-09-21 23:03:58

标签: mysql

我有两个代表历史数据的表,它们都有一个“src”列,表示该数据的主表中的主键。

例如

主要表格是

tbl_user        tbl_email
________        _________
user_pk         email_pk
username        email
email_pk        tstamp
tstamp

历史记录表基本上与原始字符匹配,表示来自主表的源主键记录的“src”列。

tbl_user_hist                 tbl_email_hist
______________                ______________
user_pk                       email_pk
src_user_pk                   src_email_pk
username                      email
email_pk                      tstamp
tstamp                      

所以,如果您有主键1的电子邮件记录,并且您将电子邮件从bob@gmail.com更改为bob@hotmail.com,然后再将其更改为bob@yahoo.com

你的tbl_email_hist看起来像这样

email_pk     src_email_pk     email                tstamp
1                   1         bob@gmail.com        2012-01-01 04:06:28
2                   1         bob@hotmail.com      2012-03-01 04:06:28
3                   1         bob@yahoo.com        2012-07-01 04:06:28

让我们说bobs的原始用户名是rsmith,然后它被改为bsmith然后再回到rsmith2。但是这些用户名更改并不一定与电子邮件更改的时间戳一致。

所以类似地,用户历史表看起来像

tbl_user_hist
User_pk     src_user_pk     username    email_pk      tstamp
1           1               rsmith      1             2012-01-01 04:08:28
2           1               bsmith      1             2012-02-01 04:01:28
3           1               rsmith2     1             2012-05-01 04:05:28

所以我想要创建一个能够根据时间戳和相关的email_pk记录查找正确的电子邮件历史记录的查询...这意味着在更改用户记录时该字段的值是多少。 因此,在某种程度上,我需要在电子邮件hist表中找到src_email_pk与用户hist表中的email_pk匹配的记录,但该电子邮件历史记录的tstamp是最高日期,同时仍然< =用户表中的时间戳。

最后我的数据看起来像这样

Username     email              username_timestamp
Rsmith       bob@gmail.com      2012-01-01 04:08:28
Bsmith       bob@hotmail.com    2012-02-01 04:01:28
Rsmith2      bob@hotmail.com    2012-05-01 04:05:28

换句话说,反映修改/创建用户名记录时电子邮件列的值。

2 个答案:

答案 0 :(得分:0)

您可以尝试这样的事情:

SELECT username, email, tbl_user_hist.tstamp
FROM tbl_user_hist 
INNER JOIN tbl_email_hist AS tbl_email_hist1 ON tbl_user_hist.email_pk = tbl_email_hist1.src_email_pk 
WHERE src_user_pk = 1
AND tbl_email_hist1.email_pk IN (
    SELECT tbl_email_hist2.email_pk FROM tbl_email_hist2
    WHERE tbl_user_hist.email_pk = tbl_email_hist2.src_email_pk
    AND tbl_email_hist2.tstamp <= tbl_user_hist.tstamp
    ORDER BY tbl_email_hist2.tstamp DESC
    LIMIT 1
)

答案 1 :(得分:0)

刚才意识到我从来没有回答过这个问题......以上建议的答案无法解决你在一个子条款中有一个Limit语句但我认为它导致了问题的IN。

以下sql语句解决了MySQL中的问题

        Select u.username,
        (Select email
        FROM
        (SELECT tbl_user_hist.src_user_pk, tbl_user_hist.username, tbl_email_hist.email,
        tbl_email_hist.src_email_pk, tbl_email_hist.tstamp, tbl_user_hist.user_pk
        FROM  tbl_email_hist 
        INNER JOIN
        tbl_user_hist ON tbl_email_hist.src_email_pk = tbl_user_hist.email_pk AND
        tbl_email_hist.src_email_pk = tbl_user_hist.email_pk AND 
                              tbl_email_hist.tstamp <= tbl_user_hist.tstamp) as e
        where e.user_pk = u.user_pk ORDER BY e.tstamp desc Limit 1) as email,
        u.tstamp as username_tstamp 

        from tbl_user_hist as u