2015-12-26 6 views
0

在一個絕對錯誤代碼只元的表格選擇,我試圖做這樣的事情:從其中aa列包含從另一列

SELECT * FROM table2 WHERE 
table2.items CONTAINS ONLY ELEMENTS FROM table1.item 

這是一個有點混亂,但I'l嘗試解釋:

我已經一個表(表1),其具有與一個元件的列中的每一行中(讓我們稱之爲A,B,C,d)

id - [item] 

1 - ["A"] 
2 - ["B"] 
3 - ["C"] 
4 - ["D"] 

然後,我有另一個表(表2)其列包含字符串像:

TABLE2 
row# - [items] 

row1 - ["A, B"] 
row2 - ["A, B, C"] 
row3 - ["A, B, C, E"] 

我要的是從包含存在於表1只元素,所以ROW1和ROW2,在這個例子表2只選擇行。

是否可以在不改變表格結構的情況下做到這一點?否則,我需要做哪些改變?

--------- [編輯] -------------

所以我改變了我的結構,以便能夠使用IN操作符和它的工作(幾乎)很好! 雖然有新問題發生。 由於我的table2字符串有不同的長度,我新的table2有一些空的單元格。

--- [更新] ---

所以,如果我想檢查是否

|item1|item2|item3|item4| row | 
| A | B | C |  | 2 | 

2行是table1.item(同上),這些條件我的一個要求是

WHERE NULL IN table1.item 

它不是!我需要的是隻檢查項目是否在其他表格中,當項目不是NULL時。我試着玩那個

+0

那麼,有什麼新的表2的結構?對於這個最小的例子,我想你只需要一個唯一的標識符(ID),一個非唯一值(A,B或C等)和一個group_id來關聯相關的值。 – Redbeard011010

回答

2

是的,這是可能的。一個簡單的方法是使用子查詢。這將是這樣的:

|ID | Value | Group_id| 
| 1 | A | 1  | 
| 2 | B | 1  | 
| 3 | C | 1  | 
| 4 | A | 2  | 
| 5 | B | 2  | 

這將是':

SELECT * FROM table1 WHERE some_value IN (SELECT some_value from table2); 

這將從如果你的表2是這樣的表2中的列some_value

其中SOME_VALUE存在table1的恢復一切A,B,C'都在組1中,而組2中的'A,B'。現在,您可以非常容易地以不同的行檢索與任何組關聯的所有值。據我最初的問題可以知道,這個表不應該有任何NULL值(正如你在更新中提到的那樣)

現在,要確定所有具有table1中存在的唯一元素的組,可能:

SELECT group_id FROM table2 WHERE group_id NOT IN (SELECT group_id FROM table2 WHERE value NOT IN (SELECT value from table1)); 

這產生一組包含在表1的所有值的結果,然後返回該組的外側值的所有group_ids,然後否定這一點。有點複雜,有可能有更好的方法來做到這一點...

+0

這不需要我的table2爲每個「item」分隔列,而不是僅包含所有項目的字符串? – KamenPurin

+0

它會的,是的。你需要研究的是所謂的標準化。我們希望在任何給定的「單元格」中只有單個值。因此,對於您的示例,您可能需要第三張表來保存每個值。例如:您不必讓Table2.Row1同時擁有'A'和'B',您可以爲該行分配一個Group_ID,創建一個名爲Groups的第三個表,將兩行插入Group_IDs(每個值爲一行),並給這些行使用與Table2.Row1現在具有的值相同的Group_ID。這是將多個值與「父」記錄相關聯的常用方法 – Redbeard011010

+0

經過一些工作後,它幾乎可以工作。介意看看OP的編輯部分? – KamenPurin

2

您的數據佈局非常差。在SQL中,將行列表存儲在行中是一個壞主意。原因如下:

  • 在關係數據模型中,每列應存儲一個「事物」。
  • 關係數據庫有很好的存儲列表的方式。它被稱爲表格。
  • 數據庫無法強制使用外鍵關係。

有時候,你會被其他人的糟糕設計決定所困住。 MySQL有一些可以提供幫助的功能。舉例來說,如果「清單」只是逗號分隔的字符串:

SELECT t2.items 
FROM table2 t2 LEFT JOIN 
    table1 t1 
    ON find_in_set(t1.item, t2.items) > 0 
GROUP BY t2.items -- or this should really be an id column if available 
HAVING COUNT(*) = LENGTH(t2.items) - LENGTH(REPLACE(t2.ITEMS, ',', '')); 

你的列表格式有空格,所以你需要將其刪除:

SELECT t2.items 
FROM table2 t2 LEFT JOIN 
    table1 t1 
    ON find_in_set(t1.item, replace(t2.items, ' ', '')) > 0 
GROUP BY t2.items -- or this should really be an id column if available 
HAVING COUNT(*) = LENGTH(t2.items) - LENGTH(REPLACE(t2.ITEMS, ',', ''));