2014-06-13 19 views
0

我想從我的分類表使用我創建的父路徑得到結果。 當我使用手動數據啓動WHERE IN請求時,它可以很好地工作。 當我與子查詢動態地嘗試相同的請求,我只有一個結果,而不是4預期。 我不明白爲什麼,你能幫我嗎?在哪裏子查詢不工作如預期

http://sqlfiddle.com/#!2/88b68/6

/*Working query*/ 
SELECT t.id_categorie FROM t 
WHERE t.id_categorie IN (1396,1399,1403,1412) 

/*Not working by subquery ??*/ 
SELECT cat.id_categorie FROM t as cat 
WHERE 
cat.id_categorie IN (SELECT REPLACE(t.path,'.',',') FROM t WHERE t.id_categorie = 1412) 

由於通過提前

問候,

+0

這是因爲't.path'是'varchar'列而不是'INT'。 – Rahul

+0

查看FIND_IN_SET(),雖然這種問題可能是設計不佳的症狀。也就是說,物化路徑是一種可接受的策略。 – Strawberry

回答

1

使用in用逗號分隔的列表中沒有你想要的東西。即使你使用子查詢。你可以試試這個:

SELECT cat.id_categorie 
FROM t cat 
WHERE EXISTS (SELECT 1 
       FROM t 
       WHERE t.id_categorie = 1412 AND 
        find_in_set(cat.id_categorie, REPLACE(t.path, '.', ',')) > 0 
      ); 

我不知道你的數據是什麼樣子,甚至這是什麼查詢應該做的(這似乎很奇怪的是,子查詢是在同一個表作爲外部查詢)。但是,通常情況下,您想要將表格存儲在表格中而不是分隔列表中。你看,SQL有一個列表的內置數據結構。它被稱爲表格。

1

這不起作用的原因是,你的內部SELECT產生一個逗號分隔的VARCHAR,而不是四個單獨的整數。

在MySQL中,你可以使用find_in_set,像這樣:

SELECT cat.id_categorie FROM t as cat 
WHERE find_in_set(cat.id_categorie, (
    SELECT REPLACE(t.path,'.',',') 
    FROM t WHERE t.id_categorie = 1412)) 

我所做的是用電話代替IN表達在查詢中find_in_set,把其他所有相同。

Demo

然而,這種解決方案是根本性的缺陷,因爲它存儲在單個列中的多個值來表示一個多到多的關係。實現此要求的更好方法是使用將表的各行連接到相關行的單獨表。

+0

謝謝,我明白了:-)我使用這個解決方案來獲取Breadcrumb而不是遞歸查詢,你能解釋一下更好的實踐嗎? – user3384179

+0

@ user3384179如果我正確理解你想達到的目標,請查看[這個問題的答案](http://stackoverflow.com/q/18603372/335858),它們展示瞭如何執行一個關係到自我在MySQL中。 – dasblinkenlight