结果根据 JOIN 语法而变化

Posted

技术标签:

【中文标题】结果根据 JOIN 语法而变化【英文标题】:results change depending on JOIN syntax 【发布时间】:2011-05-03 14:14:57 【问题描述】:

也许我在这里有一个完整的细分,但 JOIN ONJOIN USING 不应该在相同的字段下产生相同的结果吗?

例如

SELECT * FROM racks r join rack_positions p on (r.rack_id=p.rack_id);//46 rows
SELECT * FROM racks r join rack_positions p using (rack_id);//zero rows

那么为什么上面的查询不产生相同的结果呢? (我只是打赌我会因为没有弄清楚这一点而自责。)

CREATE TABLE 语句

CREATE TABLE  `racks` (
  `rack_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `watersystem_id` int(10) unsigned NOT NULL,
  `pgroup_id` int(10) unsigned DEFAULT NULL,
  `rack_name` varchar(20) NOT NULL,
  `barcode_id` int(10) unsigned DEFAULT NULL,
  `row_max` int(10) unsigned NOT NULL DEFAULT '0',
  `spigot_max` int(10) unsigned NOT NULL DEFAULT '0',
  `added_by` int(10) unsigned DEFAULT NULL,
  `added_on` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `modded_by` int(10) unsigned DEFAULT NULL,
  `modded_on` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`rack_id`),
  UNIQUE KEY `watersystem_id` (`watersystem_id`,`rack_name`) USING BTREE,
  UNIQUE KEY `FK_racks_2` (`barcode_id`) USING BTREE,
  KEY `pgroup_id` (`pgroup_id`),
  CONSTRAINT `FK_racks_2` FOREIGN KEY (`barcode_id`) REFERENCES `barcodes` (`barcode_id`),
  CONSTRAINT `racks_ibfk_1` FOREIGN KEY (`watersystem_id`) REFERENCES `watersystems` (`watersystem_id`),
  CONSTRAINT `racks_ibfk_2` FOREIGN KEY (`pgroup_id`) REFERENCES `perm_groups` (`pgroup_id`) ON DELETE SET NULL
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;


CREATE TABLE  `rack_positions` (
  `pos_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `rack_id` int(10) unsigned NOT NULL,
  `row_num` tinyint(3) unsigned NOT NULL,
  `spigot_num` tinyint(3) unsigned NOT NULL,
  `operating` tinyint(1) DEFAULT '1' COMMENT 'set to false if location cannot be used',
  `notes` text COMMENT 'optional note about why a location might be non-operational',
  `barcode_id` int(10) unsigned DEFAULT NULL,
  `added_by` int(10) unsigned DEFAULT NULL,
  `added_on` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `modded_by` int(10) unsigned DEFAULT NULL,
  `modded_on` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`pos_id`),
  UNIQUE KEY `FK_locations_2` (`barcode_id`) USING BTREE,
  KEY `rack_id` (`rack_id`),
  KEY `FK_rack_positions_3` (`added_by`),
  KEY `FK_rack_positions_4` (`modded_by`),
  CONSTRAINT `FK_rack_positions_4` FOREIGN KEY (`modded_by`) REFERENCES `users` (`user_id`) ON DELETE SET NULL,
  CONSTRAINT `FK_locations_2` FOREIGN KEY (`barcode_id`) REFERENCES `barcodes` (`barcode_id`),
  CONSTRAINT `FK_rack_positions_3` FOREIGN KEY (`added_by`) REFERENCES `users` (`user_id`) ON DELETE SET NULL,
  CONSTRAINT `rack_positions_ibfk_1` FOREIGN KEY (`rack_id`) REFERENCES `racks` (`rack_id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=98 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;

【问题讨论】:

奇怪的是,关闭连接并重新打开它似乎已经解决了这个问题。我希望这并不意味着数据库以某种方式损坏。 【参考方案1】:

根据 SQL-92,连接结果应该几乎相同。唯一的区别是 USING 语法应该返回一个名为 rack_id 的第一列的结果,而 ON 语法应该从两个表中返回 rack_id 列。

【讨论】:

以上是关于结果根据 JOIN 语法而变化的主要内容,如果未能解决你的问题,请参考以下文章

1025关于explain的补充1

多表关联查询语法?

对于SQL的Join,在学习起来可能是比较乱的。我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚。Codin

查询包含多个 JOIN 时访问 SQL 语法错误(缺少运算符)

我的带有 JOIN 的 UPDATE 的 SQL 语法有啥问题?

SQL 中的语法顺序与执行顺序