SQL-交换两列部分值

问题描述:

背景:level_video_image表里ad_level1_id,ad_level2_id字段至入库时候,存在部分写反了,即:

正常:ad_level1_id=123,ad_level2_id=456

错误:ad_level1_id=456,ad_level2_id=123   

目地:交换写反的部分,ad_level1_id,ad_level2_id字段值

表名:level_video_image、qq_media_ad_info

表字段对应关系:

level_video_image 和qq_media_ad_info 字段对应关系:

level_video_image.ad_level1_id = qq_media_ad_info.campaign_id

level_video_image.ad_level2_id = qq_media_ad_info.adset_id

level_video_image.ad_level3_id = qq_media_ad_info.ad_id

level_video_image.advertiser_id = qq_media_ad_info.advertiser_id

建表语句:

-- level_video_image 主键  (`ad_level3_id`,`date`)
CREATE TABLE `level_video_image` (
  `ad_level3_id` varchar(256) NOT NULL,
  `ad_level1_id` varchar(256) NOT NULL,
  `ad_level2_id` varchar(256) NOT NULL,
  `advertiser_id` varchar(256) NOT NULL,
  `date` varchar(10) NOT NULL,
  `update_time` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`ad_level3_id`,`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- qq_media_ad_info主键(`ad_id`,`adset_id`,`campaign_id`,`channel_id`,`advertiser_id`)
CREATE TABLE `qq_media_ad_info` (
  `ad_id` varchar(128) NOT NULL COMMENT '广告id',
  `adset_id` varchar(128) NOT NULL COMMENT '广告组id',
  `campaign_id` varchar(128) NOT NULL COMMENT '广告系列id',
  `channel_id` varchar(128) NOT NULL COMMENT '媒体id',
  `advertiser_id` varchar(128) NOT NULL COMMENT '广告账户id',
  `update_time` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`ad_id`,`adset_id`,`campaign_id`,`channel_id`,`advertiser_id`),
  KEY `ix_advertiser_id` (`advertiser_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

解决方案:

1.改入库的code,更正对应关系

2.将入错的值,使用sql语句update成正常的样子

UPDATE 
	level_video_image a,
	level_video_image b
SET a.ad_level1_id = b.ad_level2_id,
	a.ad_level2_id = b.ad_level1_id 
WHERE
	a.ad_level3_id = b.ad_level3_id 
	and a.date = b.date
	and (a.ad_level3_id, a.date) IN (
		SELECT
			t2.ad_level3_id, t2.date 
		FROM
		(SELECT
			a.ad_level3_id,a.date 
		FROM
			level_video_image a,
			qq_media_ad_info b 
		WHERE
			a.ad_level3_id = b.ad_id 
			AND a.ad_level1_id = b.adset_id 
			AND a.ad_level2_id = b.campaign_id 
			) t2 
		);

易错点: 

错误写法1,直接交换

错误写法2,没给level_video_image等价条件

        a.ad_level3_id = b.ad_level3_id 
        and a.date = b.date

-- 错误写法1❌,直接交换
UPDATE 
 	level_video_image
SET ad_level1_id = ad_level2_id, 
    ad_level2_id = ad_level1_id;

-- 错误写法2❌,没给level_video_image等价条件
UPDATE 
	level_video_image as a,
	level_video_image as b
SET a.ad_level1_id = b.ad_level2_id, 
	a.ad_level2_id = b.ad_level1_id;

-- 正确写法✅ ad_level3_id, date是联合主键
UPDATE 
	level_video_image as a,
	level_video_image as b
SET a.ad_level1_id = b.ad_level2_id, 
	a.ad_level2_id = b.ad_level1_id
WHERE a.ad_level3_id = b.ad_level3_id
      AND a.date = b.date
 

数据检查:

找出ad_level1_id和ad_level2_id数据是否还存在不对应的情况
正确的情况下是:
         ad_level3_id = ad_id 
         and ad_level1_id = campaign_id
         and ad_level2_id = adset_id

SELECT
	a.ad_level3_id,a.date 
FROM
	level_video_image a,
	qq_media_ad_info b 
WHERE
	a.ad_level3_id = b.ad_id 
	AND a.ad_level1_id = b.adset_id 
	AND a.ad_level2_id = b.campaign_id;

你可能感兴趣的:(SQL,sql,mysql)