2012-09-10 73 views
1

我有一個選擇查詢來建立,我不能得到它的工作propery。我希望從更先進的MySQL開發人員那裏得到一些建議。 所以我的表是:Mysql select查詢組concat

CREATE TABLE IF NOT EXISTS `gv` ( 
`id` int(11) NOT NULL AUTO_INCREMENT, 
`option_id` int(11) NOT NULL, 
`group_id` int(11) NOT NULL, 
PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ; 

INSERT INTO `gv` (`id`, `option_id`, `group_id`) VALUES 
(1, 1, 1), 
(2, 2, 2), 
(3, 3, 2), 
(4, 4, 3), 
(5, 5, 4), 
(6, 6, 4); 

CREATE TABLE IF NOT EXISTS `igv` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`item_id` int(11) NOT NULL, 
`gv_id` int(11) NOT NULL, 
PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ; 

INSERT INTO `igv` (`id`, `item_id`, `gv_id`) VALUES 
(1, 1, 1), 
(2, 1, 3), 
(3, 2, 1), 
(4, 2, 2), 
(6, 3, 5), 
(7, 4, 2), 
(8, 2, 6); 

CREATE TABLE IF NOT EXISTS `items` (
    `item_id` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`item_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ; 

INSERT INTO `items` (`item_id`) VALUES 
(1), 
(2), 
(3), 
(4), 
(5); 

現在我會解釋這些表都在做:

  1. GV來自group_values。一個組就像一個物品。例如:顏色。

    • 每行都保存一個組的值。例如:組顏色(group_id)的紅色(option_id)。
  2. igv來自項目組值。項目是我項目中的主要實體,就像產品一樣。

    • 每行都包含項目和組值之間的關係。例如:紅色的物品。
    • 它通過gv_id(igv.gv_id = gv.id)鏈接到gv表。
  3. 項目來自項目:)我簡化了這個例子只有一列,item_id。

我需要查詢:

嗯,在我的應用我有一個選擇的項目(my_item)(0或多個組值附後)。 我需要定義完全相同的group_values的所有項目,或者沒有爲my_item組指定值。在PHP中,我可以提取所有附加的組作爲一個數組與id,也是所有group_values。但是我沒有辦法從這個數據庫中選擇我需要的東西。 我非常感謝提供給這個海量時間選擇的任何輸入。

謝謝!

一個簡短的草繪示例。在左側,我們有與所有正確項目匹配的項目(用逗號分隔)。 enter image description here

+0

你能給一個工作的例子嗎? – Neil

+0

'SELECT i.item_id,igv.id,gv.option_id,gv.group_id FROM items AS i LEFT JOIN igv ON i.item_id = igv.item_id LEFT JOIN gv ON igv.gv_id = gv.id AND gv.group_id IN(1,2) WHERE IF(gv.group_id IS NOT NULL,gv.option_id IN(1,2),1) GROUP BY i.item_id' 但爲此,我需要先處理所有提供的項目,提取附加的組和它們的值。這也沒有完全測試到我的應用程序,只有在這個測試的例子。 –

+0

對不起,但這並沒有真正幫助我。我重讀了你的問題,我假設你想將第2項與第4項匹配,因爲它們對於2的group_id都有option_id 2,並且你不想將第2項與第3項匹配,因爲它們具有不同的option_id group_id是4,但我不能告訴你是否想將項目2與項目1或項目5或兩者匹配。 – Neil

回答

2

OK,所以下手,我們需要找到一個組中的所有項目匹配的另一個項目:

SELECT igv.item_id, sigv.item_id FROM igv 
    INNER JOIN gv ON igv.gv_id = gv.id 
    INNER JOIN gv sgv ON gv.group_id = sgv.group_id 
    INNER JOIN igv sigv ON sigv.gv_id = sgv.id 
    WHERE igv.item_id = items.item_id 
    AND sigv.item_id = similar.item_id 

然後,我們是時候只關心該選項的比賽:

SELECT igv.item_id, sigv.item_id dissimilar FROM igv 
    INNER JOIN gv ON igv.gv_id = gv.id 
    INNER JOIN gv sgv ON gv.group_id = sgv.group_id 
    INNER JOIN igv sigv ON sigv.gv_id = sgv.id 
    WHERE igv.item_id = items.item_id 
    AND sigv.item_id = similar.item_id 
    AND gv.option_id != sgv.option_id 

然後我們只對上面選擇的而不是的項目感興趣。這可以使用NOT EXISTSLEFT JOIN來完成。以下是如何與NOT EXISTS做到這一點:

SELECT items.item_id, similar.item_id similar_id 
    FROM items similar 
    INNER JOIN items 
    WHERE items.item_id != similar.item_id 
    AND NOT EXISTS (
    SELECT igv.item_id, sigv.item_id dissimilar FROM igv 
     INNER JOIN gv ON igv.gv_id = gv.id 
     INNER JOIN gv sgv ON gv.group_id = sgv.group_id 
     INNER JOIN igv sigv ON sigv.gv_id = sgv.id 
     WHERE sigv.item_id = similar.item_id 
     AND igv.item_id = items.item_id 
     AND gv.option_id != sgv.option_id 
    ) 

結果:

ITEM_ID SIMILAR_ID 
1  3 
1  5 
2  4 
2  5 
3  1 
3  4 
3  5 
4  2 
4  3 
4  5 
5  1 
5  2 
5  3 
5  4 
+0

非常感謝Neil,這解決了我的問題。 但似乎我的問題正在延伸到一個新的未考慮的級別,我忘了提及,但我也可以有多個選項附加到一個項目的同一組。但是我的錯,我沒有記錄在第一次。無論如何...非常好的答案,我非常感謝! –

+0

嗯,在這種情況下,如果所有匹配的組都有匹配的選項,那麼編寫一個查詢可以識別出一個項目,儘管在你的例子中,我認爲我只能使它匹配項目2和4。 – Neil

1

更新:

根據您的評論,的邏輯,如果我正確瞭解它,你的測試數據,下表列出了導致你想爲哪個ITEM_ID您提供查詢。

id_provided | result 
-------------------- 
1    2 & 5 
2    1 & 4 & 5 
3    5 
4    2 & 5 
5    - 

如果這是正確的,下面的查詢給出了預期的結果:

SELECT 
COALESCE(i2.item_id, i.item_id) 
FROM 
items i 
LEFT JOIN igv ON igv.item_id = i.item_id 
LEFT JOIN gv ON igv.gv_id = gv.id 
LEFT JOIN gv gv2 ON gv.group_id = gv2.group_id AND gv.option_id = gv2.option_id 
LEFT JOIN igv igv2 ON gv2.id = igv2.gv_id 
LEFT JOIN items i2 ON igv2.item_id = i2.item_id 
WHERE i.item_id = $yourItemId 
AND i2.item_id != i.item_id OR i2.item_id IS NULL 



我不知道如果我明白你想要什麼,我m不知道下面的查詢是否得到你想要的,因爲你沒有說預期的輸出是什麼,你的測試數據是不夠的。總之,這裏是我的鏡頭:

SELECT DISTINCT 
i.item_id 
FROM 
items i 
LEFT JOIN igv ON igv.item_id = i.item_id 
LEFT JOIN gv ON igv.gv_id = gv.id 
GROUP BY i.item_id 
HAVING 
GROUP_CONCAT(CONCAT(COALESCE(gv.option_id, 0), COALESCE(gv.group_id, 0)) ORDER BY gv.option_id, gv.group_id SEPARATOR ':') 
= 
(
SELECT 
GROUP_CONCAT(CONCAT(COALESCE(sq_gv.option_id, 0), COALESCE(sq_gv.group_id, 0)) ORDER BY sq_gv.option_id, sq_gv.group_id SEPARATOR ':') 
FROM 
items sq_i 
LEFT JOIN igv sq_igv ON sq_igv.item_id = sq_i.item_id 
LEFT JOIN gv sq_gv ON sq_igv.gv_id = sq_gv.id 
WHERE sq_i.item_id = $yourItemId /*insert the item_id here*/ 
GROUP BY sq_i.item_id 
) 

+0

感謝您的意見。在我的測試示例中,如果我用1到5中的任何項目ID替換$ yourItemId,它只輸出提供的$ yourItemId。 所以我需要提供一個項目的ID和查詢來選擇所有其餘項目女巫: - 如果有相同的組附加,那麼該項目也必須具有相同的選項。 - 所提供項目的所有組均未附加到此項目。 所以如果我提供的項目有紅色,那麼選擇的項目必須有: - 如果顏色組通過在igv上有一行連接,則爲紅色 - 如果沒有附加顏色組,則爲任何顏色 –

+0

@ SerbuFlorin-Adrian更新了我的答案。 – fancyPants

+0

我非常感謝你的興趣,現在我想現在我解釋了理想的結果,因爲其他人可以正確理解它。所以請檢查我更新的問題 - 附圖。 –