【问题标题】:MYSQL Update rows with duplicate value but oldest dateMYSQL更新具有重复值但最旧日期的行
【发布时间】:2018-11-01 11:43:12
【问题描述】:

尝试了很多建议来让它发挥作用,很难解释,所以下面是我拥有的数据和我想要达到的结果。

如果不是 MAX Ldate,我想将“活动”列更新为 0。

ID  | SNumber | Ldate      | Active
4804  188       2015-11-17   1
4806  189       2015-11-25   1
4807  190       2015-11-25   1
4808  191       2015-11-19   1
4809  192       2015-11-19   1
4820  193       2015-11-17   1
4821  193       2016-06-08   1
4830  194       2015-11-17   1
4831  194       2016-06-08   1
4828  195       2015-11-17   1
4829  195       2016-06-08   1


ID   SNumber  Ldate       Active    
4804 188      2015-11-17  1
4806 189      2015-11-25  1
4807 190      2015-11-25  1
4808 191      2015-11-19  1
4809 192      2015-11-19  1
4820 193      2015-11-17  0
4821 193      2016-06-08  1
4830 194      2015-11-17  0
4831 194      2016-06-08  1
4828 195      2015-11-17  0
4829 195      2016-06-08  1

我可以通过“select ID, SNumber, Ldate from (select * from tbl order by SNumber, Ldate desc) x group by SNumber”来获取所有具有 MAX Ldate 的行

感谢您花时间查看!

【问题讨论】:

  • 您确定要存储派生数据吗?顺便说一句,您现有的查询依赖于旧的 hack,其结果在最新版本的 MySQL 中无法保证。 (实际上,它永远无法保证,但那是另一回事了)
  • 嗯,好的,我会寻找更好的解决方案。无论如何,感谢您的关注。

标签: mysql max


【解决方案1】:
DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,SNumber INT NOT NULL
,Ldate DATE NOT NULL
);

INSERT INTO my_table VALUES
(4804,188,'2015-11-17'),
(4806,189,'2015-11-25'),
(4807,190,'2015-11-25'),
(4808,191,'2015-11-19'),
(4809,192,'2015-11-19'),
(4820,193,'2015-11-17'),
(4821,193,'2016-06-08'),
(4830,194,'2015-11-17'),
(4831,194,'2016-06-08'),
(4828,195,'2015-11-17'),
(4829,195,'2016-06-08');

SELECT x.*
     , COALESCE(x.ldate = y.ldate,0) active 
  FROM my_table x 
  LEFT 
  JOIN 
     ( SELECT snumber
            , MAX(ldate) ldate 
         FROM my_table 
        GROUP 
           BY snumber
     ) y 
    ON y.snumber = x.snumber 
   AND y.ldate = x.ldate;

+------+---------+------------+--------+
| id   | SNumber | Ldate      | active |
+------+---------+------------+--------+
| 4804 |     188 | 2015-11-17 |      1 |
| 4806 |     189 | 2015-11-25 |      1 |
| 4807 |     190 | 2015-11-25 |      1 |
| 4808 |     191 | 2015-11-19 |      1 |
| 4809 |     192 | 2015-11-19 |      1 |
| 4820 |     193 | 2015-11-17 |      0 |
| 4821 |     193 | 2016-06-08 |      1 |
| 4830 |     194 | 2015-11-17 |      0 |
| 4831 |     194 | 2016-06-08 |      1 |
| 4828 |     195 | 2015-11-17 |      0 |
| 4829 |     195 | 2016-06-08 |      1 |
+------+---------+------------+--------+

我想不出你为什么要存储它,但是将上面的内容更改为 UPDATE 很容易。它可能看起来像这样(显然,您需要先更改上面的表格设计)...

UPDATE my_table x 
  LEFT
  JOIN 
     ( SELECT snumber
            , MAX(ldate) ldate 
         FROM my_table 
        GROUP 
           BY snumber
     ) y 
    ON y.snumber = x.snumber 
   AND y.ldate = x.ldate
   SET x.active = 0
 WHERE y.snumber IS NULL;

但我认为我通常会使用 INNER JOIN 进行 UPDATE,在这种情况下它可能看起来像这样(可能绑定在事务中)...

 UPDATE my_table SET active = 0;
 UPDATE my_table x 
   JOIN 
      ( SELECT snumber
             , MAX(ldate) ldate 
          FROM my_table 
         GROUP 
            BY snumber
      ) y 
     ON y.snumber = x.snumber 
    AND y.ldate = x.ldate
    SET x.active = 1;

【讨论】:

  • 完美运行!谢谢...是的,我确实想将其更改为更新...'足够简单'(您说起来容易)...我尝试过...但失败了。
  • 好吧,更新您的问题,向我们展示您的尝试
  • 我认为它是这样的? UPDATE my_table INNER JOIN (SELECT x.* , COALESCE(x.ldate = y.ldate,0) active FROM my_table x LEFT JOIN (SELECT snumber , MAX(ldate) ldate FROM my_table GROUP BY snumber ) y ON y.snumber = x .snumber AND y.ldate = x.ldate) tblDerived ON tblDerived.id = y.id SET my_table.active = y.active;
  • 啊,是的,你确实说过更新问题 - 抱歉,这是我在这里发布的第一个问题 - 我已经接受了你的第二个建议,我还没有进行交易......这么多学这么少时间。无论如何,非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-26
  • 2021-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-21
相关资源
最近更新 更多