【发布时间】:2019-08-07 16:48:43
【问题描述】:
我正在尝试生成完整的物料清单分解,其中显示以下内容: (a) 所有子组件在其父/高级产品之后立即出现 (b) CTE的anchor部分读取的产品等级为1 (c) 在 CTE 的递归部分中读取的组件的级别比其父组件的级别大 1
查询在 SQL Server 中有效,但在 MySQL 8 中失败。
我尝试了获取与 ROW_NUMBER() 等效的值的方法,但没有成功。我不能使用变量,因为 CTE 不允许使用这些变量。
这是我的表结构:
CREATE TABLE IF NOT EXISTS `bill_of_materials` (
`product_id_snr` varchar(40) NOT NULL,
`product_id_jnr` varchar(40) NOT NULL,
`quantity` decimal(18,9) unsigned NOT NULL DEFAULT '1.000000000',
PRIMARY KEY (`product_id_snr`,`product_id_jnr`)
) ENGINE=InnoDB;
这是我的数据:
INSERT INTO `bill_of_materials` (`product_id_snr`, `product_id_jnr`, `quantity`) VALUES ('SNAFU', 'B-2A_ASSY', 1);
INSERT INTO `bill_of_materials` (`product_id_snr`, `product_id_jnr`, `quantity`) VALUES ('SNAFU', 'TMJ_TEST', 1);
INSERT INTO `bill_of_materials` (`product_id_snr`, `product_id_jnr`, `quantity`) VALUES ('B-2A_ASSY', 'TMJ', 1);
INSERT INTO `bill_of_materials` (`product_id_snr`, `product_id_jnr`, `quantity`) VALUES ('B-2A_ASSY', 'TMJ_ASSY_B', 1);
INSERT INTO `bill_of_materials` (`product_id_snr`, `product_id_jnr`, `quantity`) VALUES ('TMJ', 'TMJ_CP', 1);
INSERT INTO `bill_of_materials` (`product_id_snr`, `product_id_jnr`, `quantity`) VALUES ('TMJ', 'TMJ_WAFER', 1);
这是在 SQL Server 中有效但在 MySQL 中失败的查询:
WITH RECURSIVE bom (sort_seq, level, product_id_snr, product_id_jnr, quantity)
AS ( SELECT CAST(CONCAT('/', LPAD(ROW_NUMBER() OVER (ORDER BY pc.product_id_snr ASC, pc.product_id_jnr ASC), 4, '0')) AS char(4000) CHARACTER SET UTF8MB4) AS sort_seq
, 1 AS level
, pc.product_id_snr, pc.product_id_jnr, pc.quantity
FROM bill_of_materials AS pc
WHERE product_id_snr='SNAFU'
UNION ALL
SELECT CONCAT(bom.sort_seq, '/', LPAD(ROW_NUMBER() OVER (ORDER BY pc.product_id_snr ASC, pc.product_id_jnr ASC), 4, '0')) AS sort_seq
, level+1, pc.product_id_snr, pc.product_id_jnr, pc.quantity
FROM bill_of_materials AS pc
INNER JOIN bom ON (pc.product_id_snr = bom.product_id_jnr)
)
SELECT bom.* FROM bom
ORDER BY sort_seq ASC
错误消息是“递归公用表表达式'bom'在递归查询块中既不能包含聚合函数也不能包含窗口函数”
预期的输出应该是:
sort_seq ;level ;product_id_snr ;product_id_jnr ;quantity
/0001 ;1 ;SNAFU ;B-2A_ASSY ;1
/0001/0001 ;2 ;B-2A_ASSY ;TMJ ;1
/0001/0002/0001 ;3 ;TMJ ;TMJ_CP ;1
/0001/0002/0002 ;3 ;TMJ ;TMJ_WAFER ;1
/0001/0003 ;2 ;B-2A_ASSY ;TMJ_ASSY_B ;1
/0002 ;1 ;SNAFU ;TMJ_TEST ;1
如果我将 ROW_NUMBER() 替换为 product_id_jnr,如下所示:
CONCAT(bom.sort_seq, '/', pc.product_id_jnr) AS sort_seq
我得到以下结果:
sort_seq ;level ;product_id_snr ;product_id_jnr ;quantity
/0001 ;1 ;SNAFU ;B-2A_ASSY ;1
/0001/TMJ ;2 ;B-2A_ASSY ;TMJ ;1
/0001/TMJ_ASSY_B ;2 ;B-2A_ASSY ;TMJ_ASSY_B ;1
/0001/TMJ/TMJ_CP ;3 ;TMJ ;TMJ_CP ;1
/0001/TMJ/TMJ_WAFER ;3 ;TMJ ;TMJ_WAFER ;1
/0002 ;1 ;SNAFU ;TMJ_TEST ;1
这是错误的,因为 TMJ_ASSY_B 出现在第 3 行,而它应该在第 5 行。
【问题讨论】:
标签: mysql common-table-expression