MySQL select 产品的所有组件
MySQL select all components of a product
我在一家汽车公司工作。我们的产品有一个 table 和产品的组件。
这是我们一个产品的树视图。产品的一部分通过装配操作制成E40。
这是来自我们 MySQL 数据库的 table-视图:
我们希望得到产品所有组件的结果。像这样:
'E40-1', 'E40-2', 'E40-3', 'E40-4', 'E40-5', 'E40-6', 'E40-6-1',
'E40-6-2'
所以结果的长度必须是 8。
我已经尝试了一些 MySQL 查询,但它们不起作用。
我试过的查询:
select alt_bilesen from urunler_seviyeler where parcano in (select parcano from urunler_seviyeler where parcano="E40")
这只给了我们产品的六部分。没有 E40-6-1 也没有 E40-6-2。
我也试过:
select alt_bilesen from urunler_seviyeler where parcano in (select alt_bilesen from urunler_seviyeler where parcano="E40")
这只给了我们产品的最低部分。 E40-6-1 和 E40-6-2。不是其他部分。
顺便说一句,我们可以使用Python。如果我们想使用 Python 我想我们必须用一些 for 循环、while 循环等来调用它。你能给我一个建议吗?谢谢。
我建议使用零件号本身:
select alt_bilesen
from urunler_seviyeler
where CONCAT(parcano, '-') like 'E40-%'
CONCAT()
防止 E400 与 E40 混淆。
否则,您需要开始使用join
s。而且,如果子部分可以嵌套得很深,你就有问题了。 MySQL 不支持分层或嵌套数据结构的查询。
MySQL 不支持 "hierarchical" 查询。可以使用多个查询将该功能模拟到有限数量的级别。查询的结果可以与 UNION ALL 操作组合。
获取按特定顺序返回的行可能会出现问题,具体取决于您需要返回行的实际条件。
一级:
SELECT t1.alt_bilesen
FROM urunler_seviyeler t1
WHERE t1.parcano = 'E40'
二级:
SELECT t2.alt_bilesen
FROM urunler_seviyeler t1
JOIN urunler_seviyeler t2
ON t2.parcano = t1.alt_bilesen
WHERE t1.parcano = 'E40'
第三级:
SELECT t3.alt_bilesen
FROM urunler_seviyeler t1
JOIN urunler_seviyeler t2 ON t2.parcano = t1.alt_bilesen
JOIN urunler_seviyeler t3 ON t3.parcano = t2.alt_bilesen
WHERE t1.parcano = 'E40'
第四级:
SELECT t4.alt_bilesen
FROM urunler_seviyeler t1
JOIN urunler_seviyeler t2 ON t2.parcano = t1.alt_bilesen
JOIN urunler_seviyeler t3 ON t3.parcano = t2.alt_bilesen
JOIN urunler_seviyeler t4 ON t4.parcano = t3.alt_bilesen
WHERE t1.parcano = 'E40'
可以将查询与 UNION ALL
集合运算符组合起来
( SELECT t1.alt_bilesen
FROM urunler_seviyeler t1
WHERE t1.parcano = 'E40'
)
UNION ALL
( SELECT t2.alt_bilesen
FROM urunler_seviyeler t1
JOIN urunler_seviyeler t2
ON t2.parcano = t1.alt_bilesen
WHERE t1.parcano = 'E40'
)
UNION ALL
( SELECT t3.alt_bilesen
FROM urunler_seviyeler t1
JOIN urunler_seviyeler t2 ON t2.parcano = t1.alt_bilesen
JOIN urunler_seviyeler t3 ON t3.parcano = t2.alt_bilesen
WHERE t1.parcano = 'E40'
)
UNION ALL
( SELECT t4.alt_bilesen
FROM urunler_seviyeler t1
JOIN urunler_seviyeler t2 ON t2.parcano = t1.alt_bilesen
JOIN urunler_seviyeler t3 ON t3.parcano = t2.alt_bilesen
JOIN urunler_seviyeler t4 ON t4.parcano = t3.alt_bilesen
WHERE t1.parcano = 'E40'
)
ORDER BY 1
可以通过在每个查询中包含文字值来包含额外的 "level" 列。要按返回列以外的其他方式进行排序,您需要在每个查询中包含一些额外的表达式...
这将比您的示例多 3 个级别,但也适用于级别较少的产品,如您的示例中所示。如果需要,您可以添加到查询中(如果任何产品的级别超过 4 个):
Fiddle 示范: http://sqlfiddle.com/#!2/681368/1/0
select t.parcano,
trim(both ', ' from
concat(group_concat(distinct t.alt_bilesen order by
t.alt_bilesen separator ', '),
', ',
ifnull(concat(group_concat(distinct l1.alt_bilesen order by
l1.alt_bilesen separator ', '),
', '),
''),
', ',
ifnull(concat(group_concat(distinct l2.alt_bilesen order by
l2.alt_bilesen separator ', '),
', '),
''),
', ',
ifnull(concat(group_concat(distinct l3.alt_bilesen order by
l3.alt_bilesen separator ', '),
', '),
''),
', ',
ifnull(concat(group_concat(distinct l4.alt_bilesen order by
l4.alt_bilesen separator ', '),
', '),
'')
)) as parts
from urunler_seviyeler t
left join urunler_seviyeler x
on x.alt_bilesen = t.parcano
left join urunler_seviyeler l1
on t.alt_bilesen = l1.parcano
left join urunler_seviyeler l2
on l1.alt_bilesen = l2.parcano
left join urunler_seviyeler l3
on l2.alt_bilesen = l3.parcano
left join urunler_seviyeler l4
on l3.alt_bilesen = l4.parcano
where x.parcano is null
group by t.parcano
要为每个部分生成一行而不是聚合列表(这是您在问题中作为预期输出放置的内容),您可以创建一个对数据进行非规范化的视图:
create denorm_vw as
select t.parcano,
t.alt_bilesen as l0,
l1.alt_bilesen as l1,
l2.alt_bilesen as l2,
l3.alt_bilesen as l3,
l4.alt_bilesen as l4
from urunler_seviyeler t
left join urunler_seviyeler x
on x.alt_bilesen = t.parcano
left join urunler_seviyeler l1
on t.alt_bilesen = l1.parcano
left join urunler_seviyeler l2
on l1.alt_bilesen = l2.parcano
left join urunler_seviyeler l3
on l2.alt_bilesen = l3.parcano
left join urunler_seviyeler l4
on l3.alt_bilesen = l4.parcano
where x.parcano is null;
然后运行:
select parcano, l0 from denorm_vw union
select parcano, l1 from denorm_vw where l1 is not null union
select parcano, l2 from denorm_vw where l2 is not null union
select parcano, l3 from denorm_vw where l3 is not null union
select parcano, l4 from denorm_vw where l4 is not null
我在一家汽车公司工作。我们的产品有一个 table 和产品的组件。
这是我们一个产品的树视图。产品的一部分通过装配操作制成E40。
这是来自我们 MySQL 数据库的 table-视图:
我们希望得到产品所有组件的结果。像这样:
'E40-1', 'E40-2', 'E40-3', 'E40-4', 'E40-5', 'E40-6', 'E40-6-1', 'E40-6-2'
所以结果的长度必须是 8。
我已经尝试了一些 MySQL 查询,但它们不起作用。
我试过的查询:
select alt_bilesen from urunler_seviyeler where parcano in (select parcano from urunler_seviyeler where parcano="E40")
这只给了我们产品的六部分。没有 E40-6-1 也没有 E40-6-2。 我也试过:
select alt_bilesen from urunler_seviyeler where parcano in (select alt_bilesen from urunler_seviyeler where parcano="E40")
这只给了我们产品的最低部分。 E40-6-1 和 E40-6-2。不是其他部分。
顺便说一句,我们可以使用Python。如果我们想使用 Python 我想我们必须用一些 for 循环、while 循环等来调用它。你能给我一个建议吗?谢谢。
我建议使用零件号本身:
select alt_bilesen
from urunler_seviyeler
where CONCAT(parcano, '-') like 'E40-%'
CONCAT()
防止 E400 与 E40 混淆。
否则,您需要开始使用join
s。而且,如果子部分可以嵌套得很深,你就有问题了。 MySQL 不支持分层或嵌套数据结构的查询。
MySQL 不支持 "hierarchical" 查询。可以使用多个查询将该功能模拟到有限数量的级别。查询的结果可以与 UNION ALL 操作组合。
获取按特定顺序返回的行可能会出现问题,具体取决于您需要返回行的实际条件。
一级:
SELECT t1.alt_bilesen
FROM urunler_seviyeler t1
WHERE t1.parcano = 'E40'
二级:
SELECT t2.alt_bilesen
FROM urunler_seviyeler t1
JOIN urunler_seviyeler t2
ON t2.parcano = t1.alt_bilesen
WHERE t1.parcano = 'E40'
第三级:
SELECT t3.alt_bilesen
FROM urunler_seviyeler t1
JOIN urunler_seviyeler t2 ON t2.parcano = t1.alt_bilesen
JOIN urunler_seviyeler t3 ON t3.parcano = t2.alt_bilesen
WHERE t1.parcano = 'E40'
第四级:
SELECT t4.alt_bilesen
FROM urunler_seviyeler t1
JOIN urunler_seviyeler t2 ON t2.parcano = t1.alt_bilesen
JOIN urunler_seviyeler t3 ON t3.parcano = t2.alt_bilesen
JOIN urunler_seviyeler t4 ON t4.parcano = t3.alt_bilesen
WHERE t1.parcano = 'E40'
可以将查询与 UNION ALL
集合运算符组合起来
( SELECT t1.alt_bilesen
FROM urunler_seviyeler t1
WHERE t1.parcano = 'E40'
)
UNION ALL
( SELECT t2.alt_bilesen
FROM urunler_seviyeler t1
JOIN urunler_seviyeler t2
ON t2.parcano = t1.alt_bilesen
WHERE t1.parcano = 'E40'
)
UNION ALL
( SELECT t3.alt_bilesen
FROM urunler_seviyeler t1
JOIN urunler_seviyeler t2 ON t2.parcano = t1.alt_bilesen
JOIN urunler_seviyeler t3 ON t3.parcano = t2.alt_bilesen
WHERE t1.parcano = 'E40'
)
UNION ALL
( SELECT t4.alt_bilesen
FROM urunler_seviyeler t1
JOIN urunler_seviyeler t2 ON t2.parcano = t1.alt_bilesen
JOIN urunler_seviyeler t3 ON t3.parcano = t2.alt_bilesen
JOIN urunler_seviyeler t4 ON t4.parcano = t3.alt_bilesen
WHERE t1.parcano = 'E40'
)
ORDER BY 1
可以通过在每个查询中包含文字值来包含额外的 "level" 列。要按返回列以外的其他方式进行排序,您需要在每个查询中包含一些额外的表达式...
这将比您的示例多 3 个级别,但也适用于级别较少的产品,如您的示例中所示。如果需要,您可以添加到查询中(如果任何产品的级别超过 4 个):
Fiddle 示范: http://sqlfiddle.com/#!2/681368/1/0
select t.parcano,
trim(both ', ' from
concat(group_concat(distinct t.alt_bilesen order by
t.alt_bilesen separator ', '),
', ',
ifnull(concat(group_concat(distinct l1.alt_bilesen order by
l1.alt_bilesen separator ', '),
', '),
''),
', ',
ifnull(concat(group_concat(distinct l2.alt_bilesen order by
l2.alt_bilesen separator ', '),
', '),
''),
', ',
ifnull(concat(group_concat(distinct l3.alt_bilesen order by
l3.alt_bilesen separator ', '),
', '),
''),
', ',
ifnull(concat(group_concat(distinct l4.alt_bilesen order by
l4.alt_bilesen separator ', '),
', '),
'')
)) as parts
from urunler_seviyeler t
left join urunler_seviyeler x
on x.alt_bilesen = t.parcano
left join urunler_seviyeler l1
on t.alt_bilesen = l1.parcano
left join urunler_seviyeler l2
on l1.alt_bilesen = l2.parcano
left join urunler_seviyeler l3
on l2.alt_bilesen = l3.parcano
left join urunler_seviyeler l4
on l3.alt_bilesen = l4.parcano
where x.parcano is null
group by t.parcano
要为每个部分生成一行而不是聚合列表(这是您在问题中作为预期输出放置的内容),您可以创建一个对数据进行非规范化的视图:
create denorm_vw as
select t.parcano,
t.alt_bilesen as l0,
l1.alt_bilesen as l1,
l2.alt_bilesen as l2,
l3.alt_bilesen as l3,
l4.alt_bilesen as l4
from urunler_seviyeler t
left join urunler_seviyeler x
on x.alt_bilesen = t.parcano
left join urunler_seviyeler l1
on t.alt_bilesen = l1.parcano
left join urunler_seviyeler l2
on l1.alt_bilesen = l2.parcano
left join urunler_seviyeler l3
on l2.alt_bilesen = l3.parcano
left join urunler_seviyeler l4
on l3.alt_bilesen = l4.parcano
where x.parcano is null;
然后运行:
select parcano, l0 from denorm_vw union
select parcano, l1 from denorm_vw where l1 is not null union
select parcano, l2 from denorm_vw where l2 is not null union
select parcano, l3 from denorm_vw where l3 is not null union
select parcano, l4 from denorm_vw where l4 is not null