我想根据从中选择的查询来更新表。从这样的表开始:
__________________________
| id | uid | uid_seq_no |
--------------------------
| 1 | a | NULL |
| 2 | a | NULL |
| 3 | b | NULL |
| 4 | a | NULL |
| 5 | b | NULL |
| 6 | b | NULL |
| 7 | a | NULL |
| 8 | c | NULL |
--------------------------
我想将uid_seq_no
更新为范围为uid
的行序列号,以便最终结果为:
__________________________
| id | uid | uid_seq_no |
--------------------------
| 1 | a | 1 |
| 2 | a | 2 |
| 3 | b | 1 |
| 4 | a | 3 |
| 5 | b | 2 |
| 6 | b | 3 |
| 7 | a | 4 |
| 8 | c | 1 |
--------------------------
我试图按如下方式执行查询:
UPDATE keySeq a
SET uid_seq_no=(
SELECT IFNULL(uid_seq_no,0)+1 FROM keySeq b
WHERE a.uid = b.uid AND uid_seq_no IS NOT NULL
ORDER BY id
LIMIT 1
);
但我明白了:Table 'a' is specified twice, both as a target for 'UPDATE' and as a separate source for data
。
我也尝试过执行它:
UPDATE keySeq a
SET uid_seq_no=(
SELECT n FROM (
SELECT IFNULL(uid_seq_no,0)+1 AS n FROM keySeq b
WHERE a.uid = b.uid AND uid_seq_no IS NOT NULL
ORDER BY id
LIMIT 1
) AS T
)
但我得Unknown column 'a.uid' in 'where clause'
。可能是因为子子查询无法访问查询范围。
现在我没有想法。
答案 0 :(得分:2)
您可以使用此查询:
UPDATE keySeq
left join (
select a.id, (SELECT count(1) + 1 FROM keySeq b
where b.uid = a.uid and b.id<a.id) Rank
from keySeq a
) xQ on xQ.Id=keySeq.id
SET keySeq.uid_seq_no=xQ.Rank;
答案 1 :(得分:0)
替代设置更新的排名值:
SELECT
id
, uid
, uid_seq_no
, (
CASE uid
WHEN @vUid
THEN @vRank := @vRank + 1
ELSE @vRank := 1 AND @vUid := uid END
) + 1 AS rank
FROM keySeq,
(SELECT @vRank := 0, @vUid := '') var
ORDER BY uid, id
答案 2 :(得分:0)
您可以使用函数rownumber。这由uid分区,如下所示。选择就像这样:
SELECT id, uid
,ROW_NUMBER() OVER (PARTITION BY uid ORDER BY id, uid ASC) [uid_seq_no]
FROM keySeq
ORDER BY id
要在更新语句中使用select,您可以使用列别名来消除更新的歧义:
UPDATE keySeq
SET uid_seq_no = dT.uid_seq_no2
FROM ( SELECT id [id2] --I use column alias here and for uid_seq_no2
,uid
, ROW_NUMBER() OVER (PARTITION BY uid ORDER BY id, uid ASC) [uid_seq_no2]
FROM keySeq K1
) AS dT
WHERE id = dT.id2
以下是我用来测试它的sqlfiddle:http://sqlfiddle.com/#!6/c5bae/1