简体   繁体   English

两个子表的MySQL JOIN问题

[英]MySQL JOIN problems with two child tables

I'm learning MySQL JOINs now and one thing I want to know is how to JOIN two child tables with one father table. 我现在正在学习MySQL JOIN,我想知道的一件事是如何用一个父表联接两个子表。

In this case, the query is this: 在这种情况下,查询是这样的:

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;

And I've inserted these values: 我插入了这些值:

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')));

But there are some problems when I want to retrieve the recorded data. 但是,当我想检索记录的数据时会有一些问题。 The NATURAL JOIN doesn't work as the expected, taking only the rows with the same token and I can't to this: NATURAL JOIN不能按预期工作,仅使用具有相同标记的行,而我不能这样做:

SELECT * 
FROM objetos 

JOIN civis 
ON(objetos.token_dono = civis.token) 

JOIN empresas 
ON(objetos.token_dono = empresas.token)

To list all "objetos" from database with correct informations. 用正确的信息列出数据库中的所有“目标”。 But as I've tested it not work. 但是,正如我测试过的那样,它不起作用。

If someone can give me a light with these problems I'll be grateful. 如果有人可以解决这些问题,我将不胜感激。

The situation you are experiencing is that the unqualified JOIN is actually interpreted as INNER JOIN see the documentation for more details. 您遇到的情况是不合格的JOIN实际上被解释为INNER JOIN ,有关更多详细信息,请参阅文档

So when you run your query the row not containing a matching token from objetos is dropped and then since no token from civis match token from empresas all rows are dropped. 因此,当您运行查询时,将删除不包含objetos的匹配token的行,然后由于civis token没有与empresas匹配的tokenempresas所有行都将被丢弃。

So from what I gather you are trying to do you will actually need to do a LEFT JOIN if you want to get all columns from all tables or separate this one query into to like so: 因此,从我收集的信息来看,如果您想从所有表中获取所有列或将此查询分为以下内容,则实际上需要执行LEFT JOIN

SELECT * FROM objetos o JOIN civis c ON (o.token_dono = c.token);

and

SELECT * FROM objetos o JOIN empresas e ON (o.token_dono = e.token);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM