删除重复项,从组中至少保留一个参数最高的重复项

时间:2019-04-25 13:24:49

标签: mysql sql

我有以下架构:

+--+------+-----+----+
|id|device|token|cash|
+--+------+-----+----+

device是唯一的,而token不是唯一的,默认情况下为null。

我要实现的是将所有重复的token值设置为默认值(空),只剩下一个具有最高cash的值。如果重复项具有相同的cash,请保留第一个。

我听说过游标,但似乎可以通过常规查询来完成。

我只是尝试遵循SELECT来查看我的想法是否正确,但看来这是错误的。

SELECT 
    *
FROM
    db.table
WHERE
    db.table.token NOT IN (SELECT 
            *
        FROM
            (
            SELECT DISTINCT
                MAX(db.table.balance)
            FROM
                db.table
            GROUP BY db.table.balance) temp
            )

例如: 查询后该表

+-----+---------+--------+-------+
| id  |  device | token  |   cash|
+-----+---------+--------+-------+
| 1   | dev_1   | tkn_1  |  3    |
| 2   | dev_2   | tkn_1  |  10   |
| 3   | dev_3   | tkn_2  |  10   |
| 4   | dev_4   | tkn_2  |  14   |
| 5   | dev_5   | tkn_3  |  10   |
| 6   | dev_6   | null   |  10   |
| 7   | dev_7   | null   |  10   |
| 8   | dev_8   | tkn_4  |  11   |
| 8   | dev_8   | tkn_4  |  11   |
| 8   | dev_8   | tkn_5  |  11   |
+-----+---------+--------+-------+

应为:

+-----+---------+--------+-------+
| id  |  device | token  |   cash|
+-----+---------+--------+-------+
| 1   | dev_1   | null   |  3    |
| 2   | dev_2   | tkn_1  |  10   |
| 3   | dev_3   | null   |  10   |
| 4   | dev_4   | tkn_2  |  14   |
| 5   | dev_5   | tkn_3  |  10   |
| 6   | dev_6   | null   |  10   |
| 7   | dev_7   | null   |  10   |
| 8   | dev_8   | tkn_4  |  11   |
| 8   | dev_8   | null   |  11   |
| 8   | dev_8   | tkn_5  |  15   |
+-----+---------+--------+-------+

预先感谢:)

2 个答案:

答案 0 :(得分:0)

尝试使用EXISTS子查询:

UPDATE yourTable t1
SET token = NULL
WHERE EXISTS (SELECT 1 FROM (SELECT * FROM yourTable) t2
              WHERE t2.token = t1.token AND
                    t2.cash > t1.cash);

Demo

请注意,此答案假设现金最高金额相同的两个令牌记录永远不会成平局。

答案 1 :(得分:0)

要在最大现金量的偶数重复项中精确设置一行,请使用id

update t join
       (select tt.*,
               (select t3.id
                from t t3
                where t3.token = tt.token
                order by t3.cash desc, id desc
               ) as max_cash_id
        from t tt
       ) tt
       on t.id = tt.id and t.id < tt.max_cash_id
    set token = null;