【问题标题】:left Join ON condition and Select where condition difference左加入 ON 条件并选择条件差异
【发布时间】:2013-03-10 23:56:23
【问题描述】:

我有三张桌子 {animal, food, animal_food}

DROP   TABLE IF EXISTS `tbl_animal`; 
CREATE TABLE `tbl_animal` (
    id_animal       INTEGER     NOT NULL PRIMARY KEY AUTO_INCREMENT,
    name            VARCHAR(25) NOT NULL DEFAULT "no name",
    sex             CHAR(1)     NOT NULL DEFAULT "M",
    size            VARCHAR(10) NOT NULL DEFAULT "Mini",
    age             VARCHAR(10) NOT NULL DEFAULT "born",
    hair            VARCHAR(5 ) NOT NULL DEFAULT "short",
    color           VARCHAR(25) NOT NULL DEFAULT "not defined",
    FOREIGN KEY (sex)           REFERENCES `tbl_sexes`    (sex),
    FOREIGN KEY (tamanio)       REFERENCES `tbl_sizes`    (size),
    FOREIGN KEY (age)           REFERENCES `tbl_ages`     (age),
    FOREIGN KEY (hair)          REFERENCES `tbl_hair_length` (hair_length),
    CONSTRAINT `uc_Info_Animal` UNIQUE (`id_animal`)           
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;




DROP    TABLE IF EXISTS `tbl_food`; 
CREATE TABLE `tbl_food` (
    id_food       INTEGER       NOT NULL PRIMARY KEY,
    type_food     VARCHAR(20)   NOT NULL DEFAULT "Other",
    label         VARCHAR(50)   NOT NULL,
    CONSTRAINT `uc_Info_Food`   UNIQUE  (`id_food`)     
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;


DROP    TABLE IF EXISTS `animal_food`; 
CREATE  TABLE `animal_food` (
    id_animal       INTEGER     NOT NULL,
    food            VARCHAR(50) NOT NULL DEFAULT "",
    quantity        VARCHAR(50) NOT NULL DEFAULT "",        
    times           VARCHAR(50) NOT NULL DEFAULT "",
    description     VARCHAR(50) NOT NULL DEFAULT "",            
    date_last   DATE DEFAULT '0000-00-00 00:00:00',     
    date_water      DATE DEFAULT '0000-00-00 00:00:00',
    CONSTRAINT fk_ID_Animal_Food FOREIGN KEY (id_animal) REFERENCES `tbl_animal`(id_animal)  
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

我有一个视图,我根据 ID 选择 animal 和 animal_food 中的值列

CREATE VIEW `CAT_animal_food` AS
       SELECT a.name, a.sex,a.size,a.age,a.hair,a.color,
              a_f.*  
       FROM  `tbl_animal` a, `animal_food` a_f
       WHERE a.id_animal = a_f.id_animal;

创建一个像上面这样的视图或者加入这些动物和动物食物表会更好吗?

SELECT ...
  FROM A.table t1
  JOIN B.table2 t2 ON t2.column = t1.col

例如,这种视图和左连接之间的真正区别是什么?

【问题讨论】:

标签: mysql sql join view


【解决方案1】:

两个SELECT 语句之间的唯一区别是语法风格。两者都执行INNER JOINS。换句话说,这种风格使用了所谓的“隐式”语法:

SELECT ...
  FROM A.table t1, B.table2 t2
  WHERE t2.column = t1.col

它是“隐含的”,因为WHERE 子句隐含了连接条件。此版本使用“显式”语法:

SELECT ...
  FROM A.table t1
  JOIN B.table2 t2 ON t2.column = t1.col

大多数人更喜欢看到“显式”语法,因为它使您的代码更易于遵循;连接条件被明确理解,任何WHERE 子句都很明显。

当然,这些都与LEFT JOINS 无关。 Here is a famous link 对连接类型进行了出色的视觉描述。

【讨论】:

    【解决方案2】:

    有很大的不同。

    使用表列表的老式风格只允许 inner 连接。

    此外,在正确连接的 ON 子句中放置非关键条件可以实现 where 子句无法提供的更高性能和功能。这样做的主要原因是 ON 子句在进行连接时被评估,但 WHERE 子句在所有连接都完成后被评估。

    这里的主题太复杂了,无法做到公正。

    【讨论】:

    • f aliased 是什么意思还是错字?而且我猜这个 WHERE 子句行为(发生在所有连接之后)是 MySQL 特有的,对吗?
    • @BobDuell 哎呀错字 - 它本来应该被评估(现在已修复,不感谢 iPhone 自动更正)。而“否”——这种行为适用于所有数据库。 WHERE 子句过滤结果集。 ON 子句控制连接。有一些查询只能使用 ON 子句中的条件来实现。
    • 不是我;我在 DBA 网站上问了一个问题:dba.stackexchange.com/q/36391/19088
    • @Bohemian:因为这部分:“正确的连接允许 where 子句无法提供的更高性能和能力” 显然是错误的。
    • 我的反对意见仅与性能有关,尤其是与 MySQL 有关。但是你指的是哪个其他DBMS,不能优化这个,我真的很好奇。在所有其他方面,我同意你的看法。我绝对赞成明确的JOIN synatx。
    猜你喜欢
    • 1970-01-01
    • 2015-10-26
    • 2014-11-11
    • 2014-03-29
    • 2016-11-07
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多