2012-02-26 31 views
2

我有一個MySQL表保存配置數據的行,即:MySQL的多行相同的表

id item value1 value2 
2 class ship bow 
3 class car  tires 
5 reg  ship level1 
7 reg  ship level2 
9 reg  car  level5 

我試圖創建一個選擇所有行項目=「階級」的查詢,並返回數據集匹配初始查詢+所有行,其中item ='reg'和value1 = value1(來自初始結果)。

所以在這種情況下,結果集應該是這樣的:

class ship bow reg ship level1 
class ship bow reg ship level2 
class car tires reg car level5 

我有點沮喪,並希望這是有道理的。感謝任何指向正確方向的指針!

+0

有時更容易做到這一點的東西在代碼中,不是SQL – 2012-02-26 20:38:10

+0

@Toby艾倫:是的,但是在這種情況下,SQL是非常直截了當。 – Asaph 2012-02-26 20:41:40

回答

6

您必須自行加入表格。假設你的表被稱爲configs(因爲你沒有告訴我們它叫什麼),這樣的事情應該工作:

select t1.item, t1.value1, t1.value2, t2.item, t2.value1, t2.value2 
    from configs as t1 
    inner join configs as t2 
    on t2.value1 = t1.value1 and t2.item = 'reg' 
    where t1.item = 'class'; 

如果你需要的所有行已不匹配的結果返回以及reg行,將inner join更改爲left outer join。如果您希望此查詢性能良好,請確保您在itemvalue1上有索引。

這裏是概念的快速證據顯示上述作品查詢:

mysql> create table configs (
    -> id int unsigned primary key auto_increment, 
    -> item varchar(32) not null, 
    -> value1 varchar(32) not null, 
    -> value2 varchar(32) not null, 
    -> index (item), 
    -> index (value1) 
    ->) engine=innodb charset=utf8; 
Query OK, 0 rows affected (0.01 sec) 

mysql> insert into configs (id, item, value1, value2) values 
    -> (2, 'class', 'ship', 'bow'), 
    -> (3, 'class', 'car', 'tires'), 
    -> (5, 'reg', 'ship', 'level1'), 
    -> (7, 'reg', 'ship', 'level2'), 
    -> (9, 'reg', 'car', 'level5'); 
Query OK, 5 rows affected (0.00 sec) 
Records: 5 Duplicates: 0 Warnings: 0 

mysql> select * from configs; 
+----+-------+--------+--------+ 
| id | item | value1 | value2 | 
+----+-------+--------+--------+ 
| 2 | class | ship | bow | 
| 3 | class | car | tires | 
| 5 | reg | ship | level1 | 
| 7 | reg | ship | level2 | 
| 9 | reg | car | level5 | 
+----+-------+--------+--------+ 
5 rows in set (0.00 sec) 

mysql> select t1.item, t1.value1, t1.value2, t2.item, t2.value1, t2.value2 
    -> from configs as t1 
    -> inner join configs as t2 
    -> on t2.value1 = t1.value1 and t2.item = 'reg' 
    -> where t1.item = 'class'; 
+-------+--------+--------+------+--------+--------+ 
| item | value1 | value2 | item | value1 | value2 | 
+-------+--------+--------+------+--------+--------+ 
| class | ship | bow | reg | ship | level1 | 
| class | ship | bow | reg | ship | level2 | 
| class | car | tires | reg | car | level5 | 
+-------+--------+--------+------+--------+--------+ 
3 rows in set (0.00 sec) 
+0

我認爲你有一個錯誤,因爲你在比較t2.value1 = t1.value1,因爲我認爲on子句應該是value1 = item。 – 2012-02-26 20:45:26

+0

@JamesBlack:不,我說得對。再次閱讀問題並查看他的樣本數據。 「item」列只包含「class」和「reg」的值。 'value1'列是他想要匹配的內容。 – Asaph 2012-02-26 20:48:09

+1

很好的詳細。我能夠在很短的時間內進行測試和實施。謝謝! – Jimmyb 2012-02-26 22:28:45

0
SELECT 
    t1.*, 
    t2.* 
FROM 
    table t1 
    LEFT JOIN table t2 ON t2.item = 'reg' AND t2.value1 = t1.value1 
WHERE 
    t1.item = 'class' 
+0

應該更改選擇列以匹配問題中要求的內容。另外,'table'是一個SQL保留字,所以你應該用反引號把它包圍起來,或者改成別的東西。 – Asaph 2012-02-26 20:43:45

+0

在編輯問題之前發佈了答案,我不會爲了答案的清晰而更改答案。 – too 2012-02-26 20:45:56

+0

對問題的唯一編輯是格式化。沒有發生內容編輯。您可以[查看修訂歷史記錄](http://stackoverflow.com/posts/9456891/revisions)。 – Asaph 2012-02-26 20:52:10