2012-02-09 42 views
2

我在MySQL數據庫中有一堆X.有些X不會放在一起,我想要一個包含所有X對的表格和一個表示它們是否正確的布爾值。我可以在SQL中執行並行字段嗎?

這部分很簡單:

CREATE TABLE good_x (
    X_id_1 int(10) not null , 
    X_id_2 int(10) not null , 
    is_good tinyint(1) 
    ) ; 

我的問題是:鑑於Xsub1和Xsub3一起去。

SELECT is_good from good_x where X_id_1 = "Xsub1" and X_id_2 = "Xsub3" ; 

但是,如果數據來自於Xsub3,Xsub1?我可以在表中有兩個條目:

Xsub1,Xsub3,1 
Xsub3,Xsub1,1 

但是,你必須跟蹤兩件事。在我的情況下,這是一個受控詞彙,所以我不期望有太大的變化。但是如果我想添加第三個X,Xsub5,那麼你會得到六個條目。

Xsub1,Xsub3,Xsub5,1 
Xsub1,Xsub5,Xsub3,1 
Xsub3,Xsub1,Xsub5,1 
Xsub3,Xsub5,Xsub1,1 
Xsub5,Xsub1,Xsub3,1 
Xsub5,Xsub3,Xsub1,1 

這是很難維持的。

有沒有一種方法可以拋出一堆X,兩個或更多,並將它與布爾值相關聯,所以我不必爲雙打,三元組,四元組,quints等分開表。這可能在任何SQL中,如果是這樣,語法是什麼?

+0

在這種情況下,XSUB * X *是一個ID,而不是數據本身。只是爲了明確這一部分。 – 2012-02-09 17:51:49

+0

也許你可以在查看它們之前對id值進行排序。那麼只需要一行。 – 2012-02-09 17:56:08

回答

6

存儲在表中的每個有效的分組是這樣的:

CREATE TABLE good_x (x_id CHAR, group_id INT); 

與分組種子這樣的:

INSERT INTO good_x(x_id,group_id) values ('Xsub3',1); 
INSERT INTO good_x(x_id,group_id) values ('Xsub1',1); 

和3:

INSERT INTO good_x(x_id,group_id) values ('Xsub3',2); 
INSERT INTO good_x(x_id,group_id) values ('Xsub1',2); 
INSERT INTO good_x(x_id,group_id) values ('Xsub5',2); 

現在運行SELECT像這樣:

SELECT 1 
FROM good_x 
WHERE x_id IN ([your list of values]) 
GROUP BY group_id 
HAVING count(1) = n; 
+0

我喜歡你要去的地方,它讓我想起了我已經忘記了MySQL可以做的事情,但我可能會有第三張表,x_group,然後關閉x_group.id關鍵字good_x。 我喜歡那樣。 – 2012-02-09 18:05:44

+0

請注意您的解決方案如何允許存儲不僅對,而且可以存儲任意大小的組。也許'pair_id'可以重命名:) – 9000 2012-02-09 18:11:33

+0

我在想,必須有一種更好的方式,所有的自我連接,但不能確定。 – 2012-02-09 18:14:50

2

我相信你可以使用IN子句。

SELECT is_good 
    from good_x 
where X_id_1 in ("Xsub1","Xsub3","Xsub5") 
    and X_id_2 in ("Xsub1","Xsub3","Xsub5") 
    and X_id_3 in ("Xsub1","Xsub3","Xsub5") ; 

如果你不想在diferent列中的值相同,你可以添加

and (X_id_1 <> X_id_2 
    and X_id_1 <> X_id_3 
    and X_id_2 <> X_id_3) 

這,當然,也不會當你有太多的列或不同的值是理想的。

+0

我希望能夠使用最多五個x_ids進行相同的基本查詢,所以我認爲BD的方式是最好的。但是這是我偶然學習跳過的有用的SQL。謝謝。 – 2012-02-09 19:12:41

0

使用您當前的設計,最簡單的解決方案就是確保將它們存儲在數據庫中的對中時,按順序存儲它們。

例如,對於'Xsub1'和'Xsub3'對,按字母順序存儲它們。然後對他們進行搜索時,必須按字母順序是這樣的WHERE子句中命令他們:

SELECT * FROM 
good_x 
WHERE x_id_1 = 'Xsub1' 
AND x_id_2 = 'Xsub3' 

這將避免重複,只需要預處理的最小量。

我認爲BD的解決方案更好,如果你不介意重新設計。

+0

「但是如果數據來自Xsub3,Xsub1?」我想我們需要更多地瞭解這個過程。 – 2012-02-09 18:07:40

+0

@BD,你的解決方案更好。我編輯了我的答案,但任何應用程序都可以重新排序參數。 :) – 2012-02-09 18:10:32

+0

我在別處做。對的合理代碼,但不會縮放。 – 2012-02-09 19:03:33

1

如果您以某種方式訂購X(例如,通過他們的數字人工PK),你只需要存儲一組X,而不是所有的排列。它的成本將是在查詢之前訂購X的必要條件。

OTOH查詢上市「什麼是X兼容」將變得更加昂貴(需要2個索引和2個查詢)。

您可以使用一個完全通用的解決方案,如:

create table compatible (
    group_id number not null, 
    x_id number foreign key references x(id), 
    primary key (group_id, x_id) 
); 
create unique index ... on compatible(x_id, group_id) 

要存儲的事實是,任何數量的X.是兼容的,你在compatible表中創建的多條記錄與相同的任意group_id。您可以高效地查找某些項目是否兼容,查詢其是否匹配(使用exists)。您可以高效地找到與特定X兼容的所有東西。您不受兼容項目組大小的限制,並且從不關心排列。

+0

我明白了。這只是將我創建的SQL表推到客戶端軟件上(我寫的),我希望在這種情況下,弗雷德布魯克斯是錯誤的,並且*是一個銀彈。 – 2012-02-09 19:02:37

1

一個好的解決方案依賴於is_good關係的性質和X值的位。

如果X值可以訂購,那麼你可以使用排序來存儲只用一個記錄,而不是兩個成對關係。只是存儲在x_id_1min(x1, x2),並max(x1, x2)x_id_2每次插入。然後在查詢對時使用相同的方法:select ... where x_id_1 = min(x_sub_1, x_sub_2) and x_id_2 = max(x_sub_1, x_sub_2)

如果is_good關係是對稱和可傳遞的,並且如果有一個相當小且穩定的X值集合,那麼另一種方法可能是使用按位邏輯。每一位代表一個不同的X值,並且表中的每個記錄都包含一個位模式,表示具有「1」值的所有X位彼此處於is_good關係中。查詢只需要找到設置了適當位的記錄:select ... where x_bitfield & my_query_bitfield = my_query_bitfield

+0

在這種情況下,X是id代碼,我通常將其設置爲int(10)。我想我會去BD的方式(將接受一旦我有代碼工作),部分原因是它更優雅地處理三元組,但我從來沒有想到在INSERT和WHERE部分中使用min()和max()的查詢。非常黑客,以最好的方式。謝謝。 – 2012-02-09 19:11:07

相關問題