2013-04-14 121 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