2013-04-14 124 views
0

我很难得到一个查询来产生我需要的行,要么给太少或太多的重复。关于创建SQL连接的建议

最后,我要的是能产生所有非重复资源的查询,其中CID> 0

我研究过其他的答案,但大多数只是提供了一个可行的查询。我希望答案能够帮助我和其他人更好地理解查询。谢谢!

TL; DR版本如下...

下面的查询产生的重复:

SELECT DISTINCTROW r.rid, r.rname, c.cid, c.spanclass, c.cname, u.name, r.time 
FROM rmn_resources as r, rmn_users as u, rmn_conditions as c 
WHERE c.cid=r.cid 

这是我在显示数据的尝试:

|r.rid |r.rname  |c.cid |c.spanclass  |c.cname  |u.name |r.time 
|1  |'Keyfob #1' |0  |NULL    |'Created'  |User B |'0000-00-00 00:00:00' 
|1  |'Keyfob #1' |0  |NULL    |'Created'  |User A |'0000-00-00 00:00:00' 
|2  |'Keyfob #2' |1  |'label-success' |'Available' |User B |'2013-04-13 02:17:07' 
|2  |'Keyfob #2' |1  |'label-success' |'Available' |User A |'2013-04-13 02:17:07' 
|3  |'Keyfob #3' |2  |'label-important' |'Checked out' |User B |'2013-04-13 18:11:17' 
|3  |'Keyfob #3' |2  |'label-important' |'Checked out' |User A |'2013-04-13 18:11:17' 
|5  |'Spork'  |1  |'label-success' |'Available' |User B |'2013-04-14 02:29:39' 
|5  |'Spork'  |1  |'label-success' |'Available' |User A |'2013-04-14 02:29:39' 

我有一个变化是减少重复,但仍然有两个记录,我只想要一个:

SELECT DISTINCTROW r.rid, r.rname, c.cid, c.spanclass, c.cname, u.name, r.time 
FROM rmn_resources as r, rmn_users as u, rmn_conditions as c 
WHERE c.cid=r.cid AND (u.uid=r.uid OR (r.uid=0 AND r.cid>0)) 

而另一个不产生重复,但不显示我心爱的Spork。

SELECT DISTINCTROW r.rid, r.rname, c.cid, c.spanclass, c.cname, u.name, r.time 
FROM rmn_resources as r, rmn_users as u, rmn_conditions as c 
WHERE c.cid=r.cid AND u.uid=r.uid 

(老实说,我在黑暗中拍摄在这里,试图缠斗查询)

以下是SQL形式的基本表(道歉没有TL; DR版)

表:rmn_resources

CREATE TABLE IF NOT EXISTS `rmn_resources` (
    `rid` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `rname` varchar(255) CHARACTER SET utf8 NOT NULL, 
    `oid` int(10) unsigned NOT NULL COMMENT 'owner uid in users', 
    `cid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'cid: condition id in conditions', 
    `time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT 'NULL or last changed time', 
    `uid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'user uid from users', 
    PRIMARY KEY (`rid`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ; 

INSERT INTO `rmn_resources` (`rid`, `rname`, `oid`, `cid`, `time`, `uid`) VALUES 
(1, 'Keyfob #1', 0, 0, '0000-00-00 00:00:00', 0), 
(2, 'Keyfob #2', 0, 1, '2013-04-13 08:17:07', 1), 
(3, 'Keyfob #3', 0, 2, '2013-04-14 00:11:17', 2), 
(5, 'Spork', 1, 1, '2013-04-14 08:29:39', 0); 

表:rmn_users

CREATE TABLE IF NOT EXISTS `rmn_users` (
    `uid` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) CHARACTER SET utf8 NOT NULL, 
    `email` varchar(255) CHARACTER SET utf8 NOT NULL, 
    PRIMARY KEY (`uid`), 
    UNIQUE KEY `email` (`email`), 
    KEY `name` (`name`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; 

INSERT INTO `rmn_users` (`uid`, `name`, `email`) VALUES 
(1, 'User A', '[email protected]'), 
(2, 'User B', '[email protected]'); 

表:rmn_conditions

CREATE TABLE IF NOT EXISTS `rmn_conditions` (
    `cid` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `cname` varchar(255) CHARACTER SET utf8 NOT NULL, 
    `spanclass` varchar(255) CHARACTER SET utf8 DEFAULT NULL, 
PRIMARY KEY (`cid`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; 

INSERT INTO `rmn_conditions` (`cid`, `cname`, `spanclass`) VALUES 
(0, 'Created', NULL), 
(1, 'Available', 'label-success'), 
(2, 'Checked out', 'label-important'); 

回答

0

你应该开始使用显式连接,具有重复你的问题是,因为你是跨加盟。最后一个查询是可以的,但它不会显示spork,因为您没有匹配的用户。您可以使用LEFT JOIN尽管这样的:

SELECT r.rid, r.rname, c.cid, c.spanclass, c.cname, u.name, r.time 
FROM rmn_resources AS r 
LEFT JOIN rmn_users AS u 
    ON u.uid=r.uid 
LEFT JOIN rmn_conditions AS c 
    ON c.cid=r.cid; 

http://sqlfiddle.com/#!8/4d5de/1

+0

尤里卡!我之前在条件中尝试过类似的LEFT JOIN查询,但不是用户。这导致了条款中的一些缺失列,所以我放弃了这种思维方式。这让我足够接近,并将WHERE(r.cid> 0)添加到查询指令的末尾。它。非常感谢! – Deliverator

+0

哦,谢谢你指出sqlfiddle! – Deliverator

0

您可能希望通过Visual-Representation-of-SQL-Joins阅读,以获得更好的理解,如果你还没有已经加入。

当表中包含数百万行时,与您当前使用的连接相比,当您使用特定连接时,它为您提供了巨大的优势,内存和时间明智性。

希望它有帮助。

enter image description here