我现在正在学习 MySQL JOIN,我想知道的一件事是如何 JOIN 两个子表和一个父表。
在这种情况下,查询是这样的:
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
DROP SCHEMA IF EXISTS `test` ;
CREATE SCHEMA IF NOT EXISTS `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
USE `test`;
CREATE TABLE IF NOT EXISTS `test`.`objetos` (
`idobjetos` INT(11) NOT NULL AUTO_INCREMENT ,
`modelo` VARCHAR(45) NULL DEFAULT NULL ,
`descricao` VARCHAR(45) NULL DEFAULT NULL ,
`token_dono` VARCHAR(41) NOT NULL ,
PRIMARY KEY (`idobjetos`, `token_dono`) ,
INDEX `token_dono` (`token_dono` ASC) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
CREATE TABLE IF NOT EXISTS `test`.`empresas` (
`idempresa` INT(11) NULL DEFAULT NULL AUTO_INCREMENT ,
`nome` VARCHAR(45) NULL DEFAULT NULL ,
`cnpj` VARCHAR(45) NULL DEFAULT NULL ,
`email` VARCHAR(45) NULL DEFAULT NULL ,
`telefone` VARCHAR(45) NULL DEFAULT NULL ,
`token` VARCHAR(41) NOT NULL ,
PRIMARY KEY (`idempresa`, `token`) ,
INDEX `token_empresa` (`token` ASC) ,
UNIQUE INDEX `cnpj_UNIQUE` (`cnpj` ASC) ,
UNIQUE INDEX `email_UNIQUE` (`email` ASC) ,
UNIQUE INDEX `telefone_UNIQUE` (`telefone` ASC) ,
CONSTRAINT `token_empresa`
FOREIGN KEY (`token` )
REFERENCES `test`.`objetos` (`token_dono` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
CREATE TABLE IF NOT EXISTS `test`.`civis` (
`idcivil` INT(11) NOT NULL AUTO_INCREMENT ,
`nome` VARCHAR(45) NULL DEFAULT NULL ,
`cpf` VARCHAR(45) NULL DEFAULT NULL ,
`email` VARCHAR(45) NULL DEFAULT NULL ,
`token` VARCHAR(41) NOT NULL ,
PRIMARY KEY (`idcivil`, `token`) ,
INDEX `token_civil` (`token` ASC) ,
UNIQUE INDEX `cpf_UNIQUE` (`cpf` ASC) ,
UNIQUE INDEX `email_UNIQUE` (`email` ASC) ,
CONSTRAINT `token_civil`
FOREIGN KEY (`token` )
REFERENCES `test`.`objetos` (`token_dono` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
CREATE TABLE IF NOT EXISTS `test`.`an_users` (
`id` INT(11) NULL DEFAULT NULL AUTO_INCREMENT ,
`usuario` VARCHAR(45) NULL DEFAULT NULL ,
`senha` VARCHAR(45) NULL DEFAULT NULL ,
`cod_usuario` INT(11) NOT NULL ,
PRIMARY KEY (`id`, `cod_usuario`) ,
INDEX `cod_usuario_fk` (`cod_usuario` ASC) ,
CONSTRAINT `cod_usuario_fk`
FOREIGN KEY (`cod_usuario` )
REFERENCES `test`.`empresas` (`idempresa` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
我已经插入了这些值:
INSERT INTO `mydb`.`objetos` VALUES (NULL, 'Cadeira XTT', 'Quê?', SHA1(CONCAT(3913123612,'one@gmail.com')));
INSERT INTO `mydb`.`objetos` VALUES (NULL, 'Mesa TTX', 'Hein?', SHA1(CONCAT(4313123612,'two@gmail.com')));
INSERT INTO `mydb`.`objetos` VALUES (NULL, 'Prédio TT', 'Hein?', SHA1(CONCAT(73358847000116,'buzz@gmail.com')));
INSERT INTO `mydb`.`civis` VALUES (NULL, 'One', 3913123612, 'one@gmail.com', SHA1(CONCAT(3913123612,'one@gmail.com')));
INSERT INTO `mydb`.`civis` VALUES (NULL, 'Two', 4313123612, 'two@gmail.com', SHA1(CONCAT(4313123612,'two@gmail.com')));
INSERT INTO `mydb`.`empresas` VALUES(NULL, 'Buzz', 73358847000116, 'buzz@gmail.com', 33270743, SHA1(CONCAT(73358847000116,'buzz@gmail.com')));
但是当我想取回记录的数据时出现了一些问题。 NATURAL JOIN 没有按预期工作,只采用具有相同标记的行,我不能这样做:
SELECT *
FROM objetos
JOIN civis
ON(objetos.token_dono = civis.token)
JOIN empresas
ON(objetos.token_dono = empresas.token)
用正确的信息从数据库中列出所有“objetos”。但正如我所测试的那样,它不起作用。
如果有人能帮我解决这些问题,我将不胜感激。
最佳答案
你遇到的情况是不合格JOIN
实际上被解释为 INNER JOIN
查看 documentation了解更多详情。
因此,当您运行查询时,该行不包含匹配的 token
来自 objetos
被丢弃然后因为没有来自 civis
的 token 匹配token
来自 empresas
所有行都被删除。
所以根据我收集到的你正在尝试做的事情,你实际上需要做一个 LEFT JOIN
如果你想从所有表中获取所有列或将这个查询分成这样:
SELECT * FROM objetos o JOIN civis c ON (o.token_dono = c.token);
和
SELECT * FROM objetos o JOIN empresas e ON (o.token_dono = e.token);
关于两个子表的 MySQL JOIN 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8854411/