2012-06-19 125 views
2

MySQL。兩列,同一張桌子。
第1列的product_id
第2列具有category_ids(有時2個類別,所以看起來像23,43)

如何編寫一個查詢返回的PRODUCT_ID,category_ids列表,與一個單獨的行,如果有與product_id關聯的是多於1個category_id。
將結果中逗號分隔的值從一列分隔爲兩行。 MySQL


表:

product_id | category_ids 
100  | 200,300 
101  | 201 

查詢結果:不試圖修改表

100 | 200 
100 | 300 
101 | 201 


編輯:(注)我真的不希望來操縱桌子。只是在PHP中進行查詢,所以我可以根據需要使用這些數據。

+0

你爲什麼要節約category_ids逗號分隔?這不是標準化的形式。你想要的結果結構應該在那裏。 –

+0

這幾乎是這個問題的確切副本:http://stackoverflow.com/questions/10293861/split-comma-seperated-values-in-column-mysql/10294021#10294021 –

+0

另一個問題是一個確切的副本:http ://stackoverflow.com/questions/4890968/comma-seperated-value-seperation –

回答

1

你的數據庫表的實現看起來不好設計,但在你的情況下,你需要的是GROUP_CONCAT的反向函數,但不幸的是它不存在於MySQL中。

有兩種可行的解決方案:

  1. 更改您存儲數據的方式(允許在product_id領域的重複,並把多條記錄與同product_id針對不同category_id
  2. 操縱從查詢結果在您的應用程序中(您在您的問題中提到了PHP),在這種情況下,您必須拆分category_ids列值並組裝自己的結果集

還有,我已經找到了第三個方案就是喜歡一招(使用臨時表和存儲過程),首先你的聲明此存儲過程:

DELIMITER $$ 
CREATE PROCEDURE csv_Explode(sSepar VARCHAR(255), saVal TEXT) 
body: 
BEGIN 

    DROP TEMPORARY TABLE IF EXISTS csv_Explode; 
    CREATE TEMPORARY TABLE lib_Explode(
    `pos` int unsigned NOT NULL auto_increment, 
    `val` VARCHAR(255) NOT NULL, 
    PRIMARY KEY (`pos`) 
) ENGINE=Memory COMMENT='Explode() results.'; 

    IF sSepar IS NULL OR saVal IS NULL THEN LEAVE body; END IF; 

    SET @saTail = saVal; 
    SET @iSeparLen = LENGTH(sSepar); 

    create_layers: 
    WHILE @saTail != '' DO 

    # Get the next value 
    SET @sHead = SUBSTRING_INDEX(@saTail, sSepar, 1); 
    SET @saTail = SUBSTRING(@saTail, LENGTH(@sHead) + 1 + @iSeparLen); 
    INSERT INTO lib_Explode SET val = @sHead; 

    END WHILE; 

END; $$ 
DELIMITER ; 

然後你必須調用通過在陣列中列的程序要爆炸:

CALL csv_explode(',', (SELECT category_ids FROM products WHERE product_id = 100)); 

這之後,您可以顯示這種方式在臨時表中的結果:

SELECT * FROM csv_explode; 

而且結果集將是:

+-----+-----+ 
| pos | val | 
+-----+-----+ 
| 1 | 200 | 
| 2 | 300 | 
+-----+-----+ 

這可能是你的起點......

+0

一個開發者在這之前爲我實現了類似的東西(但我不知道如何翻譯和使用再次):SELECT p.prodname,c.combinationid,CONCAT(o.voname),CONCAT(vovalue) FROM isc_product_variation_combinations爲C LEFT JOIN isc_product_variation_options鄰 ON FIND_IN_SET(o.voptionid,c.vcoptionids) LEFT JOIN isc_products AS p ON p.productid = c.vcproductid WHERE c.vcproductid = 255 – jason3w

+0

儘管這是結合了幾張表中的數據。所以認爲只用一張桌子可能會很容易。 – jason3w

+0

您發佈的查詢連接兩個不同的表格,是另一回事。在這種情況下,你有一個單一的ID表,你使用FIND_IN_SET函數加入該列... – aleroot