V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Kei001
V2EX  ›  数据库

请教大佬们一条数据库语句

  •  
  •   Kei001 · 2020-04-27 03:15:02 +08:00 · 2134 次点击
    这是一个创建于 1432 天前的主题,其中的信息可能已经有所发展或是发生改变。
    数据库刚入门,请教各位大佬。
    现在有这样的需求,我的 wordpress 博客,因为安装了某个插件,会生成另外一个阅读数。现在想把这个阅读数和 WP-PostViews 生成的阅读数合并起来。

    post_meta 表结构大概是这样:

    |post_id | meta_key | meta_value|
    |1 | views | 33 |
    |1 | raw_views | 233 |
    |2 | views | 23 |
    |2 | raw_views | 123 |

    现在想把 raw_views 的值全部加到 views 上,然后把 raw_views 全部删除。
    折腾了好久没想出来 SQL 怎么写,有求于各位 V2 大佬指点一下。
    11 条回复    2020-04-27 09:47:28 +08:00
    ra1983
        1
    ra1983  
       2020-04-27 05:58:14 +08:00   ❤️ 1
    先用 group by 算出每个 post_id 的 total views,然后 update views,最后删除 raw_views

    update pm
    set pm.meta_value = total_views
    from post_meta pm
    join
    (
    select post_id, sum(meta_value) as total_views
    from post_meta
    where meta_key in ('views', 'raw_views')
    group by post_id
    ) as t
    on pm.post_id = t.post_id
    where pm.meta_key = views

    delete from post_meta
    where meta_key = 'raw_views'
    Kei001
        2
    Kei001  
    OP
       2020-04-27 08:29:56 +08:00
    @ra1983 首先感谢大佬的解答。
    尝试了用大佬的方法,存在语法错误。

    研究了一下,如果只是选择,可以把旧的 value 和新的 value 都取出来,这个没有问题。如下
    select pm.meta_value, total_views
    from `wp_postmeta` pm
    join
    (
    select post_id, sum(meta_value) as total_views
    from wp_postmeta
    where meta_key in ('views', 'raw_pageviews')
    group by post_id
    ) as t
    on pm.post_id = t.post_id
    where pm.meta_key = 'views';

    但是加上 update ... set .. from 更新就报语法错误了
    截图: https://wxt.sinaimg.cn/large/006RKGBpgy1ge80mmdp4bj30mj0d0aao.jpg
    不知大佬能否再指点一下
    ra1983
        3
    ra1983  
       2020-04-27 08:48:17 +08:00 via Android   ❤️ 1
    @Kei001
    把 subquery 变成 temporary table
    skys215
        4
    skys215  
       2020-04-27 08:52:33 +08:00
    可以发到 sql fiddle 上
    eason1874
        5
    eason1874  
       2020-04-27 08:57:41 +08:00   ❤️ 1
    数据不多随便写都可以,数据多了就不行。给你个例子,不担保没问题,你最好复制一个表出来测试确认对了再执行到业务表。

    相加:

    UPDATE `wp_postmeta` SET `meta_value` = IFNULL(`meta_value`, 0) + IFNULL((SELECT m2.`meta_value` FROM (select * from `wp_postmeta`) AS m2 WHERE m2.`post_id` = `wp_postmeta`.`post_id` AND m2.`meta_key` LIKE 'raw_views'), 0) WHERE `wp_postmeta`.`meta_key` = 'views'

    删除:

    DELETE FROM `wp_postmeta` WHERE `wp_postmeta`.`meta_key` = 'raw_views'
    shakoon
        6
    shakoon  
       2020-04-27 09:06:12 +08:00   ❤️ 1
    @Kei001 #2 “但是加上 update ... set .. from 更新就报语法错误了” 当然要报错了,你从哪儿学来的 update 接 from 的

    update post_meta pm1
    set pm1.meta_value = (
    select sum(pm2.meta_value)
    from post_meta pm2
    where pm1.post_id = pm2.post_id
    group by pm2.post_id )
    where pm.meta_key = 'views';
    liyanggyang
        7
    liyanggyang  
       2020-04-27 09:14:39 +08:00   ❤️ 1
    UPDATE post_meta t1
    SET ( meta_value ) = ( SELECT meta_value FROM post_meta WHERE post_id = t1.post_id and meta_key = 'raw_views') + t1.meta_value
    where meta_key = 'views';
    delete from post_meta where meta_key = 'raw_views';
    zwj2885
        8
    zwj2885  
       2020-04-27 09:30:32 +08:00   ❤️ 1
    楼上的写法你用不了,估计是数据库的关系。要看你的数据库是啥,oracle 的话,可以用 merg into ...using ... on ..when matched then update 。mysql 估计 1 楼的就行
    Kei001
        9
    Kei001  
    OP
       2020-04-27 09:44:07 +08:00
    @ra1983 感谢大佬 搞定了
    Kei001
        10
    Kei001  
    OP
       2020-04-27 09:45:35 +08:00
    @eason1874 谢谢大佬指点 这条 SQL 非常好用
    Kei001
        11
    Kei001  
    OP
       2020-04-27 09:47:28 +08:00
    @shakoon 嘿嘿 初学者 谢谢大佬指点
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2822 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 14:56 · PVG 22:56 · LAX 07:56 · JFK 10:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.