如果我有一个如下所示的表 T: 其中 id 是唯一的自增主键。差异列默认为 0。我只想更新每个 id_str 组中 largestId - secondLargestId 的差异,而其余部分保持不变。
id_str id Value Difference
2380 1 21.01 0
2380 3 22.04 0
2380 5 22.65 0
2380 8 23.11 0
2380 10 35.21 0
20100 2 37.07 0
20100 4 38.17 0
20100 6 38.97 0
20103 7 57.98 0
20103 9 60.83 0
我想要的结果是:
id_str id Value Difference
2380 1 21.01 0
2380 3 22.04 0
2380 5 22.65 0
2380 8 23.11 0
2380 10 35.21 12.1
20100 2 37.07 0
20100 4 38.17 0
20100 6 38.97 0.8
20103 7 57.98 0
20103 9 60.83 2.85
如何编写查询?
最佳答案
这应该可以解决 MySQL 中的问题。
CREATE TABLE SomeTable
( id_str VARCHAR(10),
id INTEGER,
value_ DECIMAL(7,5),
difference DECIMAL(7,5)
);
INSERT INTO SomeTable VALUES(2380,1,21.01,0);
INSERT INTO SomeTable VALUES(2380,3,22.04,0);
INSERT INTO SomeTable VALUES(2380,5,22.65,0);
INSERT INTO SomeTable VALUES(2380,8,23.11,0);
INSERT INTO SomeTable VALUES(2380,10,35.21,0);
INSERT INTO SomeTable VALUES(20100,2,37.07,0);
INSERT INTO SomeTable VALUES(20100,4,38.17,0);
INSERT INTO SomeTable VALUES(20100,6,38.97,0);
INSERT INTO SomeTable VALUES(20103,7,57.98,0);
INSERT INTO SomeTable VALUES(20103,9,60.83,0);
UPDATE SomeTable,
(SELECT T1.id AS id_updt,
T1.value_ - T2.value_ AS diff_updt
FROM (SELECT id_str,
id,
value_,
(
CASE id_str
WHEN @curStr THEN @curRow := @curRow + 1
ELSE @curRow := 1
AND @curStr := id_str
END
) AS rnk
FROM SomeTable,
(SELECT @curRow := 0, @curStr := '') r
ORDER
BY id_str DESC,
id DESC
) AS T1
INNER
JOIN (SELECT id_str,
id,
value_,
(
CASE id_str
WHEN @curStr THEN @curRow := @curRow + 1
ELSE @curRow := 1
AND @curStr := id_str
END
) AS rnk
FROM SomeTable,
(SELECT @curRow := 0, @curStr := '') r
ORDER
BY id_str DESC,
id DESC
) AS T2
ON T1.id_str = T2.id_str
AND T1.rnk = 1
AND T2.rnk = 2
) AS UPDT
SET SomeTable.difference = UPDT.diff_updt
WHERE SomeTable.id = UPDT.id_updt;
已弃用的解决方案 - 这适用于支持排名功能的 DBMS。
UPDATE SomeTable
FROM ( SELECT RNK1.id AS id_updt,
RNK1.value_ - RNK2.value_ AS diff_updt
FROM (SELECT id_str,
RANK() OVER
( PARTITION BY id_str
ORDER BY id DESC
) AS id_rnk
FROM SomeTable
) AS RNK1
INNER
JOIN (SELECT id_str,
RANK() OVER
( PARTITION BY id_str
ORDER BY id DESC
) - 1 AS id_rnk_decrement
FROM SomeTable
) AS RNK2
ON RNK1.id_str = RNK2.id_str
AND RNK1.id_rnk = RNK2.id_rnk_decrement
WHERE RNK1.id_rnk = 1
) AS UPDT
SET SomeTable.difference_ = UPDT.diff_updt
WHERE SomeTable.id = UPDT.id_updt;
关于mysql - SQL 在按 column1 分组后更新 column3 并比较 column2 中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46102550/