使用 SQL 查询或 Laravel SQL 查询生成器创建 table/columns 组合
Creating table/columns combinations using SQL Query or Laravel SQL Query Builder
我有一个现有的产品变体方案。
我想创建每个生产时间、数量和变化选项的组合。
我将通过访问产品的数量、生产时间、变化和变化选项来创建一个选择表。
table_groups
+------------+
| id | title |
+----+-------+
| 1 | rug |
+----+-------+
table_days
+----+----------+------+
| id | group_id | day |
+----+----------+------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
+----+----------+------+
table_quantities
+----+----------+-----------+
| id | group_id | quantity |
+----+----------+-----------+
| 1 | 1 | 100 |
| 2 | 1 | 200 |
| 3 | 1 | 300 |
| 4 | 1 | 400 |
+----+----------+-----------+
table_attributes
+----+----------+-----------+
| id | group_id | title |
+----+----------+-----------+
| 1 | 1 | Color |
| 2 | 1 | Size |
+----+----------+-----------+
table_attribute_values
+----+----------+--------------+--------+
| id | group_id | attribute_id | title |
+----+----------+--------------+--------+
| 1 | 1 | 1 | Red |
| 2 | 1 | 1 | Yellow |
| 3 | 1 | 1 | Black |
| 4 | 1 | 2 | Small |
| 5 | 1 | 2 | Medium |
+----+----------+--------------+--------+
我准备了一个示例架构。但是,我没有得到我想要的结果。
我做了这么多:
SELECT
GROUP_CONCAT(DISTINCT days_group) as days_list,
GROUP_CONCAT(DISTINCT quantities_group SEPARATOR ',') as quantities_list,
GROUP_CONCAT(DISTINCT attribute_values_group SEPARATOR ',') as attribute_values_list
FROM
table_groups
LEFT JOIN (
SELECT days.day, days.group_id,
GROUP_CONCAT(days.day) as days_group
FROM table_days days GROUP BY days.id
) joindays ON joindays.group_id = table_groups.id
LEFT JOIN (
SELECT quantities.quantity, quantities.group_id,
GROUP_CONCAT(quantities.quantity) as quantities_group
FROM table_quantities quantities GROUP BY quantities.id
) joinquantities ON joinquantities.group_id = table_groups.id
LEFT JOIN table_attributes attributes ON attributes.group_id = table_groups.id
LEFT JOIN (
SELECT attribute_id, group_id,
GROUP_CONCAT(attribute_values.title) as attribute_values_group
FROM table_attribute_values attribute_values
GROUP BY attribute_values.attribute_id, attribute_values.id
) joinattributevalues ON joinattributevalues.attribute_id = attributes.id
GROUP BY joinattributevalues.attribute_id;
查询结果:
+---------------+-----------+-----------------+-----------------------+
| group_id | days_list | quantities_list | attribute_values_list |
+---------------+-----------+-----------------+-----------------------+
| 1 | 1,2,3 | 100,200,300,400 | Red,Yellow,Black |
| 2 | 1,2,3 | 100,200,300,400 | Small,Medium |
+---------------+-----------+-----------------+-----------------------+
我想要的正确结果应该是这样的。你能帮忙吗?
+-----------+---------------------+--------+
| group_id | combinations | price |
+-----------+---------------------+--------+
| 1 | 1-100-Red-Small | |
+-----------+---------------------+--------+
| 1 | 1-100-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 1-100-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 1-100-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 1-100-Black-Small | |
+-----------+---------------------+--------+
| 1 | 1-100-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 1-200-Red-Small | |
+-----------+---------------------+--------+
| 1 | 1-200-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 1-200-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 1-200-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 1-200-Black-Small | |
+-----------+---------------------+--------+
| 1 | 1-200-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 1-300-Red-Small | |
+-----------+---------------------+--------+
| 1 | 1-300-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 1-300-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 1-300-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 1-300-Black-Small | |
+-----------+---------------------+--------+
| 1 | 1-300-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 1-400-Red-Small | |
+-----------+---------------------+--------+
| 1 | 1-400-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 1-400-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 1-400-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 1-400-Black-Small | |
+-----------+---------------------+--------+
| 1 | 1-400-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 2-100-Red-Small | |
+-----------+---------------------+--------+
| 1 | 2-100-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 2-100-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 2-100-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 2-100-Black-Small | |
+-----------+---------------------+--------+
| 1 | 2-100-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 2-200-Red-Small | |
+-----------+---------------------+--------+
| 1 | 2-200-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 2-200-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 2-200-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 2-200-Black-Small | |
+-----------+---------------------+--------+
| 1 | 2-200-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 2-300-Red-Small | |
+-----------+---------------------+--------+
| 1 | 2-300-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 2-300-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 2-300-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 2-300-Black-Small | |
+-----------+---------------------+--------+
| 1 | 2-300-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 2-400-Red-Small | |
+-----------+---------------------+--------+
| 1 | 2-400-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 2-400-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 2-400-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 2-400-Black-Small | |
+-----------+---------------------+--------+
| 1 | 2-400-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 3-100-Red-Small | |
+-----------+---------------------+--------+
| 1 | 3-100-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 3-100-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 3-100-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 3-100-Black-Small | |
+-----------+---------------------+--------+
| 1 | 3-100-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 3-200-Red-Small | |
+-----------+---------------------+--------+
| 1 | 3-200-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 3-200-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 3-200-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 3-200-Black-Small | |
+-----------+---------------------+--------+
| 1 | 3-200-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 3-300-Red-Small | |
+-----------+---------------------+--------+
| 1 | 3-300-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 3-300-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 3-300-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 3-300-Black-Small | |
+-----------+---------------------+--------+
| 1 | 3-300-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 3-400-Red-Small | |
+-----------+---------------------+--------+
| 1 | 3-400-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 3-400-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 3-400-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 3-400-Black-Small | |
+-----------+---------------------+--------+
| 1 | 3-400-Black-Medium | |
+-----------+---------------------+--------+
注意:组、属性和属性值的数量没有限制。示例结果可能是这样的:
Attributes:
+-------+------+-------+--------+
| Color | Size | Model | Gender |
+-------+------+-------+--------+
Combinations:
+------------------------------+
| 1-100-Red-Small-Model 1-Male |
+------------------------------+
| 1-100-Red-Small-Model 2-Male |
+------------------------------+
没有必要用SQL查询来做。我们也可以使用 Laravel 查询生成器方法来做到这一点。
在此先感谢您的帮助。
这应该可以做到。将不会在 mysql 5.7 中运行,因为直到后来才包含递归 CTE,但这将允许您拥有可变数量的属性和每个 group_id attribute_values。 fiddle 是 here.
with recursive allAtts as (
/* Get our attribute list, and format it if we want; concat(a.title, ':', v.title) looks quite nice */
SELECT
att.group_id,
att.id,
CONCAT(v.title) as attDesc,
dense_rank() over (partition by att.group_id order by att.id) as attRank
FROM table_attributes att
INNER JOIN table_attribute_values v
ON v.group_id = att.group_id
AND v.attribute_id = att.id
),
cte as (
/* Recursively build our attribute list, assuming ranks are sequential and we properly linked our group_ids */
select group_id, id, attDesc, attRank from allAtts WHERE attRank = 1
union all
select
allAtts.group_id,
allAtts.id,
concat_ws('-', cte.attDesc, allAtts.attDesc) as attDesc,
allAtts.attRank
from cte
join allAtts ON allAtts.attRank = cte.attRank +1
AND cte.group_id = allAtts.group_id
)
/* Our actual select statement, which RIGHT JOINs against the table_groups
so we don't lose entries w/o attributes */
select
grp.id,
concat_ws('-', d.day, qty.quantity, cte.attDesc) as combinations
from cte
inner join (select group_id, max(attRank) as attID
from cte
group by group_id) m on cte.group_id = m.group_id and m.attID = cte.attrank
RIGHT JOIN table_groups grp ON grp.id = cte.group_id
LEFT JOIN table_days d on grp.id = d.group_id
LEFT JOIN table_quantities qty on grp.id = qty.group_id;
我有一个现有的产品变体方案。
我想创建每个生产时间、数量和变化选项的组合。
我将通过访问产品的数量、生产时间、变化和变化选项来创建一个选择表。
table_groups
+------------+
| id | title |
+----+-------+
| 1 | rug |
+----+-------+
table_days
+----+----------+------+
| id | group_id | day |
+----+----------+------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
+----+----------+------+
table_quantities
+----+----------+-----------+
| id | group_id | quantity |
+----+----------+-----------+
| 1 | 1 | 100 |
| 2 | 1 | 200 |
| 3 | 1 | 300 |
| 4 | 1 | 400 |
+----+----------+-----------+
table_attributes
+----+----------+-----------+
| id | group_id | title |
+----+----------+-----------+
| 1 | 1 | Color |
| 2 | 1 | Size |
+----+----------+-----------+
table_attribute_values
+----+----------+--------------+--------+
| id | group_id | attribute_id | title |
+----+----------+--------------+--------+
| 1 | 1 | 1 | Red |
| 2 | 1 | 1 | Yellow |
| 3 | 1 | 1 | Black |
| 4 | 1 | 2 | Small |
| 5 | 1 | 2 | Medium |
+----+----------+--------------+--------+
我准备了一个示例架构。但是,我没有得到我想要的结果。
我做了这么多:
SELECT
GROUP_CONCAT(DISTINCT days_group) as days_list,
GROUP_CONCAT(DISTINCT quantities_group SEPARATOR ',') as quantities_list,
GROUP_CONCAT(DISTINCT attribute_values_group SEPARATOR ',') as attribute_values_list
FROM
table_groups
LEFT JOIN (
SELECT days.day, days.group_id,
GROUP_CONCAT(days.day) as days_group
FROM table_days days GROUP BY days.id
) joindays ON joindays.group_id = table_groups.id
LEFT JOIN (
SELECT quantities.quantity, quantities.group_id,
GROUP_CONCAT(quantities.quantity) as quantities_group
FROM table_quantities quantities GROUP BY quantities.id
) joinquantities ON joinquantities.group_id = table_groups.id
LEFT JOIN table_attributes attributes ON attributes.group_id = table_groups.id
LEFT JOIN (
SELECT attribute_id, group_id,
GROUP_CONCAT(attribute_values.title) as attribute_values_group
FROM table_attribute_values attribute_values
GROUP BY attribute_values.attribute_id, attribute_values.id
) joinattributevalues ON joinattributevalues.attribute_id = attributes.id
GROUP BY joinattributevalues.attribute_id;
查询结果:
+---------------+-----------+-----------------+-----------------------+
| group_id | days_list | quantities_list | attribute_values_list |
+---------------+-----------+-----------------+-----------------------+
| 1 | 1,2,3 | 100,200,300,400 | Red,Yellow,Black |
| 2 | 1,2,3 | 100,200,300,400 | Small,Medium |
+---------------+-----------+-----------------+-----------------------+
我想要的正确结果应该是这样的。你能帮忙吗?
+-----------+---------------------+--------+
| group_id | combinations | price |
+-----------+---------------------+--------+
| 1 | 1-100-Red-Small | |
+-----------+---------------------+--------+
| 1 | 1-100-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 1-100-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 1-100-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 1-100-Black-Small | |
+-----------+---------------------+--------+
| 1 | 1-100-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 1-200-Red-Small | |
+-----------+---------------------+--------+
| 1 | 1-200-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 1-200-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 1-200-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 1-200-Black-Small | |
+-----------+---------------------+--------+
| 1 | 1-200-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 1-300-Red-Small | |
+-----------+---------------------+--------+
| 1 | 1-300-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 1-300-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 1-300-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 1-300-Black-Small | |
+-----------+---------------------+--------+
| 1 | 1-300-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 1-400-Red-Small | |
+-----------+---------------------+--------+
| 1 | 1-400-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 1-400-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 1-400-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 1-400-Black-Small | |
+-----------+---------------------+--------+
| 1 | 1-400-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 2-100-Red-Small | |
+-----------+---------------------+--------+
| 1 | 2-100-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 2-100-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 2-100-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 2-100-Black-Small | |
+-----------+---------------------+--------+
| 1 | 2-100-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 2-200-Red-Small | |
+-----------+---------------------+--------+
| 1 | 2-200-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 2-200-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 2-200-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 2-200-Black-Small | |
+-----------+---------------------+--------+
| 1 | 2-200-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 2-300-Red-Small | |
+-----------+---------------------+--------+
| 1 | 2-300-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 2-300-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 2-300-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 2-300-Black-Small | |
+-----------+---------------------+--------+
| 1 | 2-300-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 2-400-Red-Small | |
+-----------+---------------------+--------+
| 1 | 2-400-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 2-400-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 2-400-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 2-400-Black-Small | |
+-----------+---------------------+--------+
| 1 | 2-400-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 3-100-Red-Small | |
+-----------+---------------------+--------+
| 1 | 3-100-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 3-100-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 3-100-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 3-100-Black-Small | |
+-----------+---------------------+--------+
| 1 | 3-100-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 3-200-Red-Small | |
+-----------+---------------------+--------+
| 1 | 3-200-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 3-200-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 3-200-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 3-200-Black-Small | |
+-----------+---------------------+--------+
| 1 | 3-200-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 3-300-Red-Small | |
+-----------+---------------------+--------+
| 1 | 3-300-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 3-300-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 3-300-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 3-300-Black-Small | |
+-----------+---------------------+--------+
| 1 | 3-300-Black-Medium | |
+-----------+---------------------+--------+
| 1 | 3-400-Red-Small | |
+-----------+---------------------+--------+
| 1 | 3-400-Red-Medium | |
+-----------+---------------------+--------+
| 1 | 3-400-Yellow-Small | |
+-----------+---------------------+--------+
| 1 | 3-400-Yellow-Medium | |
+-----------+---------------------+--------+
| 1 | 3-400-Black-Small | |
+-----------+---------------------+--------+
| 1 | 3-400-Black-Medium | |
+-----------+---------------------+--------+
注意:组、属性和属性值的数量没有限制。示例结果可能是这样的:
Attributes:
+-------+------+-------+--------+
| Color | Size | Model | Gender |
+-------+------+-------+--------+
Combinations:
+------------------------------+
| 1-100-Red-Small-Model 1-Male |
+------------------------------+
| 1-100-Red-Small-Model 2-Male |
+------------------------------+
没有必要用SQL查询来做。我们也可以使用 Laravel 查询生成器方法来做到这一点。
在此先感谢您的帮助。
这应该可以做到。将不会在 mysql 5.7 中运行,因为直到后来才包含递归 CTE,但这将允许您拥有可变数量的属性和每个 group_id attribute_values。 fiddle 是 here.
with recursive allAtts as (
/* Get our attribute list, and format it if we want; concat(a.title, ':', v.title) looks quite nice */
SELECT
att.group_id,
att.id,
CONCAT(v.title) as attDesc,
dense_rank() over (partition by att.group_id order by att.id) as attRank
FROM table_attributes att
INNER JOIN table_attribute_values v
ON v.group_id = att.group_id
AND v.attribute_id = att.id
),
cte as (
/* Recursively build our attribute list, assuming ranks are sequential and we properly linked our group_ids */
select group_id, id, attDesc, attRank from allAtts WHERE attRank = 1
union all
select
allAtts.group_id,
allAtts.id,
concat_ws('-', cte.attDesc, allAtts.attDesc) as attDesc,
allAtts.attRank
from cte
join allAtts ON allAtts.attRank = cte.attRank +1
AND cte.group_id = allAtts.group_id
)
/* Our actual select statement, which RIGHT JOINs against the table_groups
so we don't lose entries w/o attributes */
select
grp.id,
concat_ws('-', d.day, qty.quantity, cte.attDesc) as combinations
from cte
inner join (select group_id, max(attRank) as attID
from cte
group by group_id) m on cte.group_id = m.group_id and m.attID = cte.attrank
RIGHT JOIN table_groups grp ON grp.id = cte.group_id
LEFT JOIN table_days d on grp.id = d.group_id
LEFT JOIN table_quantities qty on grp.id = qty.group_id;