我想问一下,对我的应用程序有什么更好的解决方案。我有1个表:标记 - 我存储标记的位置 - 名称,符号和描述。然后我有另一张表:产品 - 每个产品都有一些标记1 - N.现在我在表产品中存储产品标记 - 列prod_marks - 以逗号分隔。然后我用另一个查询得到那些标记。我从products表中获取了所有标记的ID,然后运行查询来获取它们。它是好的还是1用join和group_concat查询另一个表让我们说:prodmarks(pmark_id,pmark_prodID,pmark_markID)会更好吗?
由于
编辑:
table ci_products
table ci_marks(带符号和描述的所有可能标记)
现在我的查询如下:
SELECT `prod_id`, `prod_name`, `prod_desc`, `prod_num`, `prod_marks`, `prod_minprice`, `prod_minbid`, `prod_cat`, GROUP_CONCAT(img_url) images
FROM (`ci_products`)
JOIN `ci_prodimages` ON `ci_prodimages`.`img_pid`=`ci_products`.`prod_id`
WHERE `prod_cat` = '4'
OR `prod_cat` = '8'
OR `prod_cat` = '9'
OR `prod_cat` = '10'
GROUP BY `prod_id`
查询结果:
然后我在prod_marks中得到这样的东西:2,5,6 然后使用这些ID我运行另一个查询以获得标记'名称和描述。
第二个想法是另一个连接到新表:ci_prodmarks - 我会有pmark_id,pmark_pid(fk到prod_id),pmark_mid(fk到mark_id)以及标记符号和标记描述上的另一个group_concat
修改
这就是我现在所得到的。使用这些数据,我运行另一个查询来获取这些标记。问题是:我是否应该将另一个表格与ci_products和ci_marks相关联以形成M-N关系?此外,我想要查询以获取与其相关的标记的所有产品。当我使用JOIN时,它会为每个图像和标记产生多个产品,所以我使用了group_concat。那么我会使用另一个group_concat作为mark_mark和mark_desc吗?
修改
带有多个结果问题的关系表的新SQL
SELECT `prod_id` , `prod_name` , `prod_desc` , `prod_num` , `prod_marks` , `prod_minprice` , `prod_minbid` , `prod_cat` , GROUP_CONCAT( img_url ) images, GROUP_CONCAT( mark_mark ) marks, GROUP_CONCAT( mark_desc
SEPARATOR ";" ) mark_descriptions
FROM (
`ci_products` , `ci_marks`
)
JOIN `ci_prodimages` ON `ci_prodimages`.`img_pid` = `ci_products`.`prod_id`
JOIN `ci_prodmarks` ON `ci_prodmarks`.`pmark_pid` = `ci_products`.`prod_id`
AND ci_prodmarks.pmark_mid = ci_marks.mark_id
WHERE `prod_cat` = '4'
OR `prod_cat` = '8'
OR `prod_cat` = '9'
OR `prod_cat` = '10'
GROUP BY `prod_id` , `mark_id`
答案 0 :(得分:1)
您的一个问题是您按mark_id
分组,这意味着每个产品最终会有多行,而不是每行中的所有标记,但这只是隐藏了另一个问题。因为您有多个一对多关系,所以您在加入时会获得笛卡尔积。想象一下prod_id = 1
图片强>
pid url
--------------
1 some_url
1 some_other_url
<强>标记强>
pid mark
-------------------
1 1
1 2
当您在产品ID上加入这两个时,您最终会
pid url mark
------------------------------
1 some_url 1
1 some_url 2
1 some_other_url 1
1 some_other_url 2
所以你得到了两者的所有组合,所以当你对这些组合进行GROUP_CONCAT时,你会得到重复的。
您需要使用子查询来执行组仲裁:
SELECT p.prod_id,
p.prod_name,
p.prod_desc,
p.prod_num,
p.prod_marks,
p.prod_minprice,
p.prod_minbid,
p.prod_cat,
img.images,
m.marks,
m.mark_descriptions
FROM ci_products p
INNER JOIN
( SELECT i.img_pid, GROUP_CONCAT( i.img_url ) images
FROM ci_prodimages i
GROUP BY i.img_pid
) img
ON img.img_pid = p.prod_id
INNER JOIN
( SELECT ci_prodmarks.pmark_pid,
GROUP_CONCAT( ci_marks.mark_mark ) marks,
GROUP_CONCAT( ci_marks.mark_desc SEPARATOR ";" ) mark_descriptions
FROM ci_prodmarks
INNER JOIN ci_marks
ON ci_prodmarks.pmark_mid = ci_marks.mark_id
GROUP BY ci_prodmarks.pmark_pid
) m
ON m.pmark_pid = p.prod_id
WHERE p.prod_cat IN ('4', '8', '9', '10')
<强> Example on SQL Fiddle 强>
或者在GROUP_CONCAT中使用DISTINCT:
SELECT p.prod_id,
p.prod_name,
p.prod_desc,
p.prod_num,
p.prod_marks,
p.prod_minprice,
p.prod_minbid,
p.prod_cat,
GROUP_CONCAT( i.img_url ) images,
GROUP_CONCAT( DISTINCT m.mark_mark ) marks,
GROUP_CONCAT( DISTINCT m.mark_desc SEPARATOR ";" ) mark_descriptions
FROM ci_products p
INNER JOIN ci_prodimages i
ON i.img_pid = p.prod_id
INNER JOIN ci_prodmarks pm
ON pm.pmark_pid = p.prod_id
INNER JOIN ci_marks m
ON pm.pmark_mid = m.mark_id
WHERE p.prod_cat IN ('4', '8', '9', '10')
GROUP BY p.prod_id, p.prod_name, p.prod_desc, p.prod_num, p.prod_marks, p.prod_minprice, p.prod_minbid, p.prod_cat
<强> Example on SQL Fiddle 强>
N.B。
我也取而代之:
WHERE `prod_cat` = '4'
OR `prod_cat` = '8'
OR `prod_cat` = '9'
OR `prod_cat` = '10'
使用单个IN
语句:
WHERE p.prod_cat IN ('4', '8', '9', '10')