2013-08-16 95 views
1

我想問問什麼是我的應用程序更好的解決方案。我有1個表格:標記 - 我存儲標記的地方 - 名稱,符號和說明。然後我有另一個表:產品 - 每個產品都有一些標記1 - N.現在我在表格產品中存儲產品的標記 - 列prod_marks - 逗號分隔。然後我用另一個查詢得到這些標記。我從產品表中獲得所有標記的ID,然後運行查詢來獲取它們。這是好的或將查詢加入和group_concat到另一個表讓我們說:prodmarks(pmark_id,pmark_prodID,pmark_markID)會更好嗎?group_concat與另一個查詢

感謝

編輯:

表ci_products

enter image description here

表ci_marks enter image description here

現在我的查詢看起來像這樣(用符號和說明所有可能的標誌):

查詢
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` 

結果: enter image description here

然後我得到了prod_marks是這樣的:2,5,6 然後用那些我運行另一個查詢來獲取標記名稱和說明標識。

第二屆想法是使另一加入到新表: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` 
+2

不要在表使用逗號分隔值。使用多對多關係表。 – Barmar

+0

很難說出你在問什麼。你可以展示一個關於數據和查詢的小例子嗎? – Barmar

+0

是的,只是片刻 – DeiForm

回答

1

你的一個問題是,你是mark_id分組,這將意味着你最終每多行產品,而不是每一行中的所有標誌,但這只是隱藏了另一個問題。因爲你有多個一對多的關係,你可以在你的連接中獲得笛卡爾產品。想象一下PROD_ID下面這個簡單的例子= 1張

圖片

pid  url 
-------------- 
1  some_url 
1  some_other_url 

商標

pid  mark 
------------------- 
1  1 
1  2 

當你在你結束了

pid  url    mark 
------------------------------ 
1  some_url  1 
1  some_url  2 
1  some_other_url 1 
1  some_other_url 2 
產品ID加入這兩個

所以你得到了兩者的所有組合,所以當你對這些進行GROUP_CONCAT時,你會得到重複的。

你要麼需要使用子查詢做你的組concats:

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') 
+0

謝謝你完美的工作。花了一些時間來適應這個到我的PHP,但工作:) – DeiForm