2012-02-26 52 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