1

我有一个 MySQL 查询,我在其中关联了一个按 desc 日期排序的用户访问列表。

SELECT `id`, `name`, `date` 
FROM `logs` 
WHERE `iid` = ? 
ORDER BY `date` DESC';

每个日志都有iid, id, name, date,生成的数组也有每行的 3 个请求值。

这里以数据库为例:

| iid   | id    | name  | date              |
---------------------------------------------
| 1     | 1     | foo   | 2013-09-13 10:14  |
| 2     | 1     | foo   | 2013-09-12 08:10  |
| 2     | 1     | foo   | 2013-09-11 14:43  |
| 1     | 1     | foo   | 2013-09-10 15:12  |

iid是页面,id用户ID。

现在我需要添加第 4 列,称为lastvisit它应该包含每个用户上一次访问的日期iid
所以我应该有两个不同lastvisit的值iid

| iid   | id    | name  | date              | lastvisit         |
-----------------------------------------------------------------
| 1     | 1     | foo   | 2013-09-13 10:14  | 2013-09-12 15:12  |
| 2     | 1     | foo   | 2013-09-12 08:10  | 2013-09-11 14:43  |
| 2     | 1     | foo   | 2013-09-11 14:43  | null              |
| 1     | 1     | foo   | 2013-09-10 15:12  | null              |

我会将此列添加到数据库中,并且在每次访问时,我都会检查最近的访问以获取lastvisit要放入新条目的值。

我的问题是关于已经记录的条目,这些条目没有lastvisit.

我需要用查询填充它们,例如:

UPDATE `logs`
SET `lastvisit` = (
    SELECT `date`
    FROM `logs` 
    WHERE `id` = ? AND 'iid' = ?
    ORDER BY `date` DESC'
    LIMIT 0, 1;
)

显然这个查询不起作用,是否可以编写一个查询来为每个条目执行此任务?

4

1 回答 1

2

你很接近。您需要一个相关子查询来将内部查询连接到正在更新的外部表。我认为这会起作用:

UPDATE `logs` l
    SET `lastvisit` = (
        SELECT `date`
        FROM `logs` l2
        WHERE l2.id = l.id AND l2.iid = l.iid AND l2.date <= l.date
        ORDER BY `date` DESC'
        LIMIT 0, 1;
    );

实际上,我认为 MySQL 在使用更新表 (arrggg) 的子查询方面存在问题。您可以将其表述为更复杂的:

update logs l join
       (select l.*,
               if(@id = id and @iid = iid, @date, NULL) as prevdate,
               @id := id, @iid := iid, @date := date
        from logs l cross join
             (select @date := '', @id := '', @iid := '') const
        order by id, iid, date
       ) lprev
       on l.id = lprev.id and l.iid = lprev.iid and l.date = lprev.date
    set l.lastvisit = lprev.prevdate;
于 2013-09-13T13:55:09.753 回答