2016-06-09 44 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 
;