我运行的数据库结构有点复杂,可跟踪产品。以下是MySQL Workbench生成的图表:
在这种结构下,我有3种产品可供我添加。所有这三种产品都具有color
属性和red
选项。
我在这里设置了一个sql小提琴:http://sqlfiddle.com/#!2/68470/4显示我正在运行的查询,试图让opt_count
列在attribute
列为{{color
列的行上说3 1}}和option
列为red
。
几乎所有其他opt_count
值也都是错误的,所以我怀疑我要么没有按正确的列进行分组,要么我没有错误地接近整个问题。
如何为每一行显示正确的opt_count
?
答案 0 :(得分:1)
看看这是否有帮助
SELECT products.product_name
, products.product_id
, pvc.combination_id
, pvc.combination
, pva.attribute
, pvo.option
, COUNT(pvo.option) as opt_count
FROM (`products`)
JOIN `product_variant_combinations` pvc ON `products`.`product_id` = `pvc`.`product_id`
JOIN `product_variants` pv ON `pv`.`combination_id` = `pvc`.`combination_id`
JOIN `product_variant_ao_relation` pv_ao ON `pv_ao`.`ao_id` = `pv`.`ao_id`
JOIN `product_variant_options` pvo ON `pvo`.`option_id` = `pv_ao`.`option_id`
JOIN `product_variant_attributes` pva ON `pva`.`attribute_id` = `pv_ao`.`attribute_id`
GROUP BY 1
返回:
| PRODUCT_NAME | PRODUCT_ID | COMBINATION_ID | COMBINATION | ATTRIBUTE | OPTION | OPT_COUNT |
|--------------|------------|----------------|----------------------------------------------------|-----------|--------|-----------|
| Desk | 111025 | 4 | {"color":"Red","material":"Wood"} | color | red | 4 |
| Lamp | 111024 | 1 | {"color":"Red"} | color | red | 3 |
| T shirt | 111026 | 6 | {"color":"Red","size":"Small","material":"Cotton"} | color | red | 18 |
答案 1 :(得分:1)
正如其他人所说,您的架构是问题,因为您有多对多关系(许多产品可能有很多选项),这使得查询更加困难。
这是一个查询,为您提供所要求的确切输出。它显示每个选项,分配了多少选项的唯一产品(COUNT(distinct product_id)),并提供以逗号分隔的已分配的product_id值列表。
SELECT pvo.option,
count(distinct product_id),
group_concat(distinct product_id) products
FROM (`products`)
JOIN `product_variant_combinations` pvc using(`product_id`)
JOIN `product_variants` pv using(`combination_id`)
JOIN `product_variant_ao_relation` pv_ao using(`ao_id`)
JOIN `product_variant_options` pvo using(`option_id`)
JOIN `product_variant_attributes` pva using(`attribute_id`)
group by pvo.option;
这是红色的输出:
red 3 111026,111025,111024
见这里: http://sqlfiddle.com/#!2/68470/133
您询问了如何添加属性:
SELECT pva.attribute, pvo.option, count(distinct product_id), group_concat(product_id)
FROM (`products`)
JOIN `product_variant_combinations` pvc using(`product_id`)
JOIN `product_variants` pv using(`combination_id`)
JOIN `product_variant_ao_relation` pv_ao using(`ao_id`)
JOIN `product_variant_options` pvo using(`option_id`)
JOIN `product_variant_attributes` pva using(`attribute_id`)
group by pva.attribute, option
您必须在SELECT子句中使用GROUP BY每个非聚合表达式。在这种情况下,两个聚合表达式是COUNT和GROUP_CONCAT,因此,您必须GROUP BY pva.attribute,pvo.option
您可能希望在GROUP BY上找到一个很好的SQL教程。
答案 2 :(得分:0)
使用GROUP BY
子句时,需要使用聚合函数(例如max
,avg
或sum
)调用所有未分组的字段,以告知数据库如何将它们聚合成分组行。
因为您按单个字段分组并且只为另一个字段指定了聚合,所以结果本质上不可靠且“杂乱” - 您实际上是根据找到的行的磁盘存储顺序获得随机结果。
MySQL是唯一一个默认情况下不强制执行此要求的RDBMS(甚至presents it as a feature) - 所有其他常见数据库(如SQL Server,PostgreSQL和Oracle)都会对您编写的查询产生严重错误。严格检查此规则can be enabled if you wish,但这会打破许多错误编写的遗留应用程序。
答案 3 :(得分:0)
在处理MySQL和你的问题之间存在一些关系,但问题实际上源于“组合行”
group-by包含组合行,该行具有连续列表。 Group-by表示数据库引擎将创建数据集,其中每列中的值相同。
您的组合列包含
{ “颜色”: “红”, “材料”: “木”} {“红色”} { “颜色”: “红”, “大小”: “小”, “材料”: “棉花”} { “颜色”: “红”, “大小”: “中”, “材料”: “棉花”} { “颜色”: “红”, “大小”: “大”, “材料”: “棉花”}
这些都是唯一值,因此使opt_count为1。
为了解决这个问题,您需要获得一个基于color = red的opt_count作为派生表,然后将其重新连接到包含您感兴趣的其余数据的表中
我相信这个查询会返回你想要的内容。请注意,由于组合列的非唯一性,您不会为每个产品返回一行。
-- Outer query to return the product/option/attribute information, plus the count from the derived table
SELECT
products.product_name, products.product_id,
product_variant_combinations.combination_id, product_variant_combinations.combination,
product_variant_attributes.attribute,
product_variant_options.option,
red_products.option_count
FROM product_variant_combinations
INNER JOIN product_variants
ON product_variant_combinations.combination_id = product_variants.combination_id
INNER JOIN product_variant_ao_relation
ON product_variants.ao_id = product_variant_ao_relation.ao_id
INNER JOIN product_variant_options
ON product_variant_ao_relation.option_id = product_variant_options.option_id
INNER JOIN product_variant_attributes
ON product_variant_ao_relation.attribute_id = product_variant_attributes.attribute_id
INNER JOIN products
ON product_variant_combinations.product_id = products.product_id
INNER JOIN
(
-- Inner table to count the distinct products with the color "red"
SELECT COUNT(DISTINCT product_variant_combinations.product_id) AS option_count,
product_variant_attributes.attribute_id,
product_variant_options.option_id
FROM product_variant_attributes
INNER JOIN product_variant_ao_relation
ON product_variant_attributes.attribute_id = product_variant_ao_relation.attribute_id
INNER JOIN product_variant_options
ON product_variant_ao_relation.option_id = product_variant_options.option_id
INNER JOIN product_variants
ON product_variant_ao_relation.ao_id
INNER JOIN product_variant_combinations
ON product_variants.COMBINATION_ID = product_variant_combinations.COMBINATION_ID
WHERE product_variant_options.option = 'red'
AND product_variant_attributes.attribute = 'color'
GROUP BY product_variant_attributes.attribute_id, product_variant_options.option_id
) AS red_products
ON product_variant_attributes.attribute_id = red_products.attribute_id
AND product_variant_options.option_id = red_products.option_id