我有3个表鸣叫,室,room_tweet:MySQL数据库连接表和搜索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
一旦感谢您的时间。
太感谢你了,你已经解决了我问题。 我必须改变唯一的事情(防止推特重复),将分隔符移动到第一个LEFT JOIN -----> LEFT JOIN room_tweet as rt ON t.id = rt.tweet_id AND rt.room_id = 21 – Kyle