mysql JOIN查询返回多次相同的行

时间:2016-06-09 19:06:09

标签: php mysql

我正在尝试显示构建的扇区1中的所有通用斜率(来自game_slopes)(即存在于game_created_slopes中)和status_id = 1。

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。

2 个答案:

答案 0 :(得分:1)

您应该使用单个表格,因为您使用了第二个连接

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

如果您离开这两张表,您将获得表格的笛卡尔积

答案 1 :(得分: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
;