Mysql 通过对表本身执行查询来更新表
我想根据从自身选择的查询更新表。从这样的表格开始:Mysql 通过对表本身执行查询来更新表,mysql,sql,Mysql,Sql,我想根据从自身选择的查询更新表。从这样的表格开始: __________________________ | id | uid | uid_seq_no | -------------------------- | 1 | a | NULL | | 2 | a | NULL | | 3 | b | NULL | | 4 | a | NULL | | 5 | b | NULL | | 6 | b
__________________________
| 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
);
但我得到:表“a”被指定了两次,既作为“更新”的目标,也作为数据的单独源
我还尝试执行它,如:
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
)
但是我在where子句中得到了未知的列a.uid。可能是因为子查询无法访问查询范围
现在我没有主意了
示例表:您可以使用此查询:
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;
为更新设置秩值的备选方案:
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
您可以使用函数rownumber。这是按uid分区的,如下所示。一个选择是这样的:
SELECT id, uid
,ROW_NUMBER() OVER (PARTITION BY uid ORDER BY id, uid ASC) [uid_seq_no]
FROM keySeq
ORDER BY id
要在update语句中使用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
下面是我用来测试的SQLFIDLE: