2016-06-09 72 views
0

我試圖顯示扇區1中構建(即存在於game_created_slopes)和status_id = 1的所有通用斜率(來自game_slopes)。mysql JOIN查詢返回多次相同的行

CREATE TABLE `game_created_slopes` (
    `id_created_slopes` int(11) NOT NULL, 
    `id_player` int(11) NOT NULL, 
    `id_slope` int(11) NOT NULL, 
    `custom_name` varchar(45) DEFAULT NULL, 
    `slope_condition` int(3) NOT NULL, 
    `id_status` int(11) NOT NULL, 
    `end_construction` datetime NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

INSERT INTO `game_created_slopes` (`id_created_slopes`, `id_player`, `id_slope`, `custom_name`, `slope_condition`, `id_status`, `end_construction`) VALUES 
(168, 46, 6, 'Slope 24', 50, 1, '2016-05-17 17:01:25'), 
(170, 46, 1, 'Slope 1', 1, 1, '2016-06-06 18:35:22'), 
(172, 46, 7, 'Slope 3', 100, 1, '2016-06-08 21:48:43'); 


CREATE TABLE `game_slopes` (
    `id_slope` int(11) NOT NULL, 
    `id_sector` int(11) NOT NULL, 
    `name_english` varchar(45) NOT NULL, 
    `name_french` varchar(45) DEFAULT NULL, 
    `length` int(11) NOT NULL, 
    `id_difficulty` int(11) NOT NULL, 
    `cost` int(11) NOT NULL, 
    `building_time` int(11) NOT NULL, 
    `reputation` int(11) NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 


INSERT INTO `game_slopes` (`id_slope`, `id_sector`, `name_english`, `name_french`, `length`, `id_difficulty`, `cost`, `building_time`, `reputation`) VALUES 
(1, 1, 'Slope 1', 'Piste 1', 2000, 1, 1000000, 13, 3000), 
(6, 1, 'Slope 2', 'Piste 2', 1000, 2, 100000, 15, 5000), 
(7, 2, 'Slope 3', 'Piste 3', 1400, 3, 200000, 5, 8000), 
(8, 1, 'Slope 5', 'Piste 5', 1456, 4, 105000, 20, 5040); 

不幸的是,兩個結果應返回(ID 168和170)被返回三次,每次。我注意到,如果game_created_slopes包含5行,那麼這兩個ID將返回每個 5次。

(ID 172是扇區2,所以它不返回)

我的查詢:

$this->db->distinct('game_slopes.id_slope, game_slopes.id_sector, game_created_slopes.id_slope, game_created_slopes.id_created_slopes, game_created_slopes.id_player'); 
$this->db->from('game_slopes, game_created_slopes'); 
$this->db->join('game_created_slopes as created_slopes_tbl', 'game_slopes.id_slope = created_slopes_tbl.id_slope', 'inner'); 
$this->db->where('created_slopes_tbl.id_status', '1'); 
$this->db->where('game_slopes.id_sector', '1); 
$this->db->where('created_slopes_tbl.id_player', $currentUserID); 
$query = $this->db->get(); 

PHP代碼:

$num_slopes_for_this_sector = $this->Model->get_slopes_($currentUserID); 

foreach ($num_slopes_for_this_sector->result() as $row){ 
     echo '<br>SECTOR :'. $i; 
     echo '<br>id_created_slopes:'.$row->id_created_slopes; 
} 

什麼是錯我的查詢?它應該只返回兩個ID。

+0

不批評,只是想知道好奇心,爲什麼你會用這種方式構建查詢,而不僅僅是一個更直接的'SELECT fields FROM joined tables WHERE conditions met' approach?它看起來像一個相當簡單的SQL查詢被切碎和洗牌。 – Uueerdo

+0

我很欣賞這個評論,實際上我願意接受任何讓查詢更簡單的建議。你有沒有提供這種語法的例子? – remyremy

回答

1

你應該從單一的表怎麼一回事,因爲你使用加入第二

$this->db->from('game_slopes'); 

如果離開這兩個表中,您獲得笛卡爾積兩個表

+0

太容易了!非常感謝! – remyremy

0

要顯示直接翻譯使用,線線...

SELECT DISTINCT game_slopes.id_slope, game_slopes.id_sector, game_created_slopes.id_slope, game_created_slopes.id_created_slopes, game_created_slopes.id_player 
FROM game_slopes, game_created_slopes 
INNER JOIN game_created_slopes as created_slopes_tbl ON game_slopes.id_slope = created_slopes_tbl.id_slope 
WHERE created_slopes_tbl.id_status = 1 
AND game_slopes.id_sector = 1 
AND created_slopes_tbl.id_player = $currentUserID 
; 

我格式化它更像是這雖然(也消除意外交叉連接,並更新所使用的參考/別名)

SELECT DISTINCT game_slopes.id_slope, game_slopes.id_sector 
    , created_slopes_tbl.id_slope, created_slopes_tbl.id_created_slopes 
    , created_slopes_tbl.id_player 
FROM game_slopes 
    INNER JOIN game_created_slopes AS created_slopes_tbl 
     ON game_slopes.id_slope = created_slopes_tbl.id_slope 
WHERE created_slopes_tbl.id_status = 1 
    AND game_slopes.id_sector = 1 
    AND created_slopes_tbl.id_player = $currentUserID 
; 

最後,雖然我對php並不完全熟悉,我會用?替換$currentUserID並將其變成參數化查詢。


雖然,我是一個懶惰的打字員(當別名替換爲子查詢時,別名會有所幫助)。

SELECT DISTINCT gs.id_slope, gs.id_sector 
    , gcs.id_slope, gcs.id_created_slopes 
    , gcs.id_player 
FROM game_slopes AS gs 
    INNER JOIN game_created_slopes AS gcs 
     ON gs.id_slope = gcs.id_slope 
WHERE gcs.id_status = 1 
    AND gs.id_sector = 1 
    AND gcs.id_player = $currentUserID 
;