mysql - SQL 在按 column1 分组后更新 column3 并比较 column2 中的值

标签 mysql sql

如果我有一个如下所示的表 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/

相关文章:

SQL Server 登录禁用 Windows 身份验证

php - 在 MySQL 中存储页面浏览量的最佳方式是什么?

mysql - 对人口统计数据集进行健壮的 SQL 查询

php - 如何在mysql中散列自动增量

php - 如果主键缺少序列号,MySQLi 查询将不起作用

php - 按 id mysql/php 出现的最高次数对数据库表进行排序

mysql - 希望在一个查询中完成两个方程并使用最终结果

php - 本地 xampp wordpress 安装 - 找不到 wp-blog-header.php

php - 与 ID 数组相比,检测数据库中要删除的字段的最佳方法

MySQL:CONCAT/SUBSTRING:这不起作用,因为我使用的是 int 变量吗?