2016-09-28 81 views
0

我有以下tabels作爲例子創建具有一個視圖上加入多個標籤

球拍

-------------------- 
| id | Name  | 
| 1 | Raquet 1 | 
| 2 | Raquet 2 | 
-------------------- 

字符串

-------------------- 
| id | Name  | 
| 1 | String 1 | 
| 2 | String 2 | 
| 3 | String 3 | 
| 4 | String 4 | 
-------------------- 

標籤

-------------------- 
| id | Name  | 
| 1 | Label 1 | 
| 2 | Label 2 | 
| 3 | Label 3 | 
| 4 | Label 4 | 
-------------------- 

Raquet_Labels

-------------------- 
| r_id | l_id | 
| 1 | 1  | 
| 1 | 2  | 
| 2 | 3  | 
| 2 | 4  | 
-------------------- 

String_Labels

-------------------- 
| s_id | l_id | 
| 1 | 1  | 
| 1 | 2  | 
| 1 | 3  | 
| 2 | 1  | 
| 2 | 2  | 
| 3 | 1  | 
| 3 | 3  | 
| 4 | 3  | 
| 4 | 4  | 
-------------------- 

我想匹配所有列表中的所有的球拍,絃樂組合,其中字符串應該有相應的球拍的所有標籤。

例如

球拍1具有標籤1,2 球拍2具有標籤3,4

字符串1具有標籤1,2,3 字符串2具有標籤1,2 字符串3具有標籤1,3 字符串4具有標籤3,4

從上述 - 字符串1具有一切在球拍1個 字符串2的一部分已全部是球拍1一部分的標籤標籤0字符串3不具有任何球拍 串4的一部分具有一切在球拍2

繼部分標籤是期望

-------------------- 
| r_id | s_id | 
| 1 | 1  | 
| 1 | 2  | 
| 2 | 4  | 
-------------------- 

SQL創建所需要的數據的標籤。

create table raquet(id integer not null, name varchar(256) not null); 
insert into raquet values (1,'Raquet 1'), (2,'Raquet 2'), (3,’Raquet 3’); 
create table string(id integer not null, name varchar(256) not null); 
insert into string values (1,'String 1'), (2,'String 2'), (3,'String 3'), (4,'String 4'); 
create table label(id integer not null, name varchar(256) not null); 
insert into label values (1,'Label 1'), (2,'Label 2'), (3,'Label 3'), (4,'Label 4'); 
create table raquet_labels(r_id integer not null, l_id integer not null); 
insert into raquet_labels values (1,1), (1,2), (2,3), (2,4); 
create table string_labels(s_id integer not null, l_id integer not null); 
insert into string_labels values (1,1), (1,2), (1,3), (2,1), (2,2), (3,1), (3,3), (4,3), (4,4); 
+2

那麼,你有什麼已經嘗試過? – Gasper

+0

聽起來像作業lol – Zi0n1

+0

@Gasper - 我試了很長時間。我無法真正獲得循環或某種遞歸的好方法。可能是這不是正確的思考方式。但是,我沒有一個具體的步驟,我可以說,我得到了一些答案。我主要是在嘗試與路口相交。 –

回答

0

這是一個看起來很簡單的任務,但不是。這裏有一種方法:

  1. 我們創建了我們希望看到的記錄,即所有的raquet標籤與所有字符串組合在一起。這是表Raquet_Labels與表String的交叉連接。這是我們希望看到的所有比賽,現在我們必須測試這些字符串是否真的實現了這一點。
  2. 我們外加現有的球拍標籤,所以我們得到所有的匹配和所有不匹配。
  3. 我們彙總我們的數據:對於一個raquet和一個字符串:我們只有匹配或不匹配?我們可以用count來做到這一點; count(*)統計所有記錄,但count(<column from the outer-joined table>)只計數匹配項。要麼計數相等(每個標籤匹配)或不相等。

查詢:

select rl.r_id, s.id as s_id 
from raquet_labels rl 
cross join string s 
left join string_labels sl on sl.s.id = s.id and sl.l_id = rl.l_id 
group by rl.r_id, s.id 
having count(*) = count(sl.s_id); 

這裏是另一種方式:

  1. 我們創建了一套球拍和字符串的所有可能的組合。這是兩張表的交叉連接。
  2. 對於每個這樣的組合,我們檢查是否找到沒有匹配字符串標籤的球拍標籤。如果不是這樣,沒有沒有匹配的球拍標籤,所以我們保持對。

查詢:

select r.id as r_id, s.id as s_id 
from racket r 
cross join string s 
where not exists 
(
    select l_id from raquet_labels rl where rl.r_id = r.id 
    except 
    select l_id from string_labels sl where sl.s_id = s.id 
); 
+0

這是一個很大的幫助。第一個查詢給了我正在尋找的確切結果。第二個有一些額外的條目,因爲交叉聯接null。 假設有在raquests另一條目(3,Raquet3),其結果是 - '1,1- 1,2- 2,4- 3,1 3,2 3,3 3,4' –

+0

啊,你說得對;第二個查詢只有在每個球拍至少有一個標籤時才能正常工作。 –

+0

...但有人可能會爭辯說,每個字符串然後提供其所有標籤,所以結果仍然是正確的:-) –

相關問題