我有一个MySQL查询,我通过关联获取用户按访问日期排序的访问列表。
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。
现在我需要添加名为lastvisit
的第4列,其中应包含每位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;
)
显然这个查询不起作用,是否可以编写查询来为每个条目执行此任务?
答案 0 :(得分: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;