-- Product base price version: table + bms_product_country.ppv_id -- Run once on existing DB. New installs: see bms_init.sql CREATE TABLE IF NOT EXISTS `bms_product_price_version` ( `ppv_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '产品基础价格版本ID', `product_code` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '产品代码', `product_id` bigint(20) DEFAULT NULL COMMENT '对应 bms_product.product_id(该版本产品行)', `version_no` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '版本号 V1/V2', `version_seq` int(11) NOT NULL COMMENT '版本序号,用于自动+1', `effective_date` date NOT NULL COMMENT '生效日期', `expire_date` date DEFAULT NULL COMMENT '失效日期(空=长期;下一版生效日=本版失效日)', `status` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '0待生效 1已生效 2已失效', `created_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建人', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `updated_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新人', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`ppv_id`), UNIQUE KEY `uk_ppv_code_seq` (`product_code`,`version_seq`), UNIQUE KEY `uk_ppv_code_eff` (`product_code`,`effective_date`), KEY `idx_ppv_code_status` (`product_code`,`status`), KEY `idx_ppv_product_id` (`product_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='产品基础价格版本'; SET @col_exists := ( SELECT COUNT(1) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'bms_product_country' AND COLUMN_NAME = 'ppv_id' ); SET @sql := IF(@col_exists = 0, 'ALTER TABLE `bms_product_country` ADD COLUMN `ppv_id` bigint(20) DEFAULT NULL COMMENT ''产品基础价格版本ID bms_product_price_version.ppv_id'' AFTER `product_id`, ADD KEY `idx_product_country_ppv` (`ppv_id`)', 'SELECT 1'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; INSERT INTO `bms_product_price_version` ( product_code, product_id, version_no, version_seq, effective_date, expire_date, status, created_by, create_time ) SELECT t.product_code, ( SELECT p.product_id FROM bms_product p WHERE p.product_code = t.product_code AND p.effective_date = t.effective_date ORDER BY p.product_id ASC LIMIT 1 ) AS product_id, CONCAT('V', t.version_seq) AS version_no, t.version_seq, t.effective_date, t.expire_date, CASE WHEN t.expire_date IS NOT NULL AND t.expire_date <= CURDATE() THEN '2' WHEN t.effective_date > CURDATE() THEN '0' ELSE '1' END AS status, 'migrate' AS created_by, NOW() AS create_time FROM ( SELECT g.product_code, g.effective_date, g.expire_date, ( SELECT COUNT(1) FROM ( SELECT product_code, effective_date FROM bms_product_country WHERE effective_date IS NOT NULL GROUP BY product_code, effective_date ) earlier WHERE earlier.product_code = g.product_code AND earlier.effective_date <= g.effective_date ) AS version_seq FROM ( SELECT product_code, effective_date, MAX(expire_date) AS expire_date FROM bms_product_country WHERE effective_date IS NOT NULL GROUP BY product_code, effective_date ) g ) t WHERE NOT EXISTS ( SELECT 1 FROM bms_product_price_version v WHERE v.product_code = t.product_code AND v.effective_date = t.effective_date ); UPDATE bms_product_country c INNER JOIN bms_product_price_version v ON v.product_code = c.product_code AND v.effective_date = c.effective_date SET c.ppv_id = v.ppv_id WHERE c.ppv_id IS NULL AND c.effective_date IS NOT NULL;