2014-02-11 43 views
0

我有3个表鸣叫room_tweetMySQL数据库连接表和搜索WHERE <多列>

 tweet     room       room_tweet 
+----+------+-----+  +----+------+-----+  +----+---------+----------+----------+ 
| id | text | ... |  | id | name | ... |  | id | room_id | tweet_id | disabled | 
+----+------+-----+  +----+------+-----+  +----+---------+----------+----------+ 
| 10 | a... | ... |  | 20 | a... | ... |  | 80 | 20 | 10 |  1 | 
| 11 | b... | ... |  | 21 | b... | ... |  | 81 | 20 | 11 |  0 | 
| 12 | c... | ... |  | 22 | c... | ... |  | 82 | 21 | 10 |  1 | 
| 13 | d... | ... |  +----+------+-----+  | 83 | 20 | 12 |  1 | 
+----+------+-----+        | 84 | 22 | 10 |  0 | 
               | 85 | 21 | 11 |  1 | 
               +----+---------+----------+----------+ 

我需要一个查询,得到所有鸣叫和表演已禁用状态在特定房间

所有鸣叫显示在所有客房,每个鸣叫禁用状态,并在每不同的房间(相同鸣叫在每个房间不同禁用状态)这是通过room_tweet表达到的。

这是我到目前为止已经编写的查询:

SELECT t.id AS tweet_id, t.text AS tweet, rt.disabled, r.id AS room_id, r.name AS room 
FROM tweet as t 
LEFT JOIN room_tweet as rt ON t.id = rt.tweet_id 
LEFT JOIN room as r ON rt.room_id = r.id 
WHERE r.id = 21 OR r.id IS NULL 

并非所有鸣叫是在room_tweet表,其关联到一个房间。因此,许多鸣叫将在结果NULL参照室设置,和同样为的房间,一些客房将关联到他们没有鸣叫。 [这并不意味着鸣叫不应该在结果显示设置]

所有鸣叫应该出现在结果集一次(仅一次)用的禁用状态[1,0或NULL]。

这将是一个简单的查询,如果所有鸣叫碰巧对room_tweet表关联,但这种情况并非如此。由于推文是全天创建的,并且房间是随机创建的room_tweet表不会,也不应该有所有关联。

Result without WHERE: 
+----------+-------+----------+---------+------+ 
| tweet_id | tweet | disabled | room_id | room | 
+----------+-------+----------+---------+------+ 
| 10 | a... | 1  | 20 | a... | 
| 10 | a... | 1  | 21 | b... | 
| 10 | a... | 0  | 22 | c... | 
| 11 | b... | 0  | 20 | a... | 
| 11 | b... | 1  | 21 | b... | 
| 12 | c... | 1  | 20 | a... | 
| 13 | d... | NULL | NULL | NULL | 
+----------+-------+----------+---------+------+ 
Tweets are duplicated multiple times ex: tweet 10 shows 3 times. 

Result with (WHERE r.id = 21 OR r.id IS NULL) 
+----------+-------+----------+---------+------+ 
| tweet_id | tweet | disabled | room_id | room | 
+----------+-------+----------+---------+------+ 
| 10 | a... | 1  | 21 | b... | 
| 11 | b... | 1  | 21 | b... | 
| 13 | d... | NULL | NULL | NULL | 
+----------+-------+----------+---------+------+  
Tweets are missing!, only tweet with id 10, 11 and 13 show up. This is because 
the other tweets have been associated with other rooms and therefore are not 
**NULL** anymore. (All tweets should appear once). 

正如你可以在结果集,看到不是所有鸣叫正在显示(当在正在使用),另一个问题是,鸣叫已与多个相关房间上的room_tweet表,因此他们被复制在结果集。 (我只希望看到每个鸣叫一次!)

所以,问题是:我缺少的是对查询,是它甚至可能得到结果,我很期待?

是否有可能解决此问题?如果是这样,我的问题是查询问题还是表错误?

如果你想在这里测试的查询是建立在phpMyAdmin所有的表格和数据的SQL:

CREATE TABLE `room` (`id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(60) NOT NULL, `...` varchar(3) NOT NULL DEFAULT '...', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=23 ; 
CREATE TABLE `tweet` (`id` int(11) NOT NULL AUTO_INCREMENT, `text` varchar(140) NOT NULL, `...` varchar(3) NOT NULL DEFAULT '...', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=14 ; 
CREATE TABLE `room_tweet` (`id` int(11) NOT NULL AUTO_INCREMENT, `room_id` int(11) NOT NULL, `tweet_id` int(11) NOT NULL, `disabled` tinyint(1) NOT NULL, PRIMARY KEY (`id`), KEY `fk_room_tweet_1` (`room_id`), KEY `fk_room_tweet_2` (`tweet_id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=86 ; 
ALTER TABLE `room_tweet` ADD CONSTRAINT `fk_room_tweet_1` FOREIGN KEY (`room_id`) REFERENCES `room` (`id`), ADD CONSTRAINT `fk_room_tweet_2` FOREIGN KEY (`tweet_id`) REFERENCES `tweet` (`id`);  
INSERT INTO `room` (`id`, `name`, `...`) VALUES (20, 'a...', '...'), (21, 'b...', '...'), (22, 'c...', '...');  
INSERT INTO `tweet` (`id`, `text`, `...`) VALUES (10, 'a...', '...'), (11, 'b...', '...'), (12, 'c...', '...'), (13, 'd...', '...'); 
INSERT INTO `room_tweet` (`id`, `room_id`, `tweet_id`, `disabled`) VALUES (80, 20, 10, 1), (81, 20, 11, 0), (82, 21, 10, 1), (83, 20, 12, 1), (84, 22, 10, 0), (85, 21, 11, 1); 

我试过JOIN,INNER JOIN,LEFT JOIN,RIGHT JOIN,中午时似乎解决我的问题。

感谢您的时间,并再次,我唯一需要的是一个结果集是获取所有鸣叫,显示上特定房间禁用状态。如果它没有已禁用状态NULL应该出现。

迄今为止最好的结果是这样的:

再次
SELECT t.id AS tweet_id, t.text AS tweet, rt.disabled, r.id AS room_id, r.name AS room 
FROM tweet as t 
LEFT JOIN room_tweet as rt ON t.id = rt.tweet_id 
LEFT JOIN room as r ON rt.room_id = r.id 

一旦感谢您的时间。

回答

0

您需要的r.id条件移到on条款:

SELECT t.id AS tweet_id, t.text AS tweet, rt.disabled, r.id AS room_id, r.name AS room 
FROM tweet as t 
LEFT JOIN room_tweet as rt ON t.id = rt.tweet_id 
LEFT JOIN room as r ON rt.room_id = r.id and r.id = 21; 

与此查询,当他们在房间的东西只会匹配21

+0

太感谢你了,你已经解决了我问题。 我必须改变唯一的事情(防止推特重复),将分隔符移动到第一个LEFT JOIN -----> LEFT JOIN room_tweet as rt ON t.id = rt.tweet_id AND rt.room_id = 21 – Kyle