1

我有两个表示历史数据的表,它们都有一个“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 记录找到正确的电子邮件历史记录……这意味着在用户记录更改时该字段的值是什么。因此,在某种程度上,我需要在电子邮件历史表中找到 src_email_pk 与用户历史表中的 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

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

4

2 回答 2

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
)
于 2012-09-23T17:37:04.067 回答
0

刚刚意识到我从来没有回答过这个问题..上面建议的答案不起作用尽管我认为它是导致问题的 IN,但您会收到关于在子条款中有 Limit 语句的错误。

下面这个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
于 2014-09-04T19:27:41.027 回答