Mysql 此选项应使用联接还是子查询?

Mysql 此选项应使用联接还是子查询?,mysql,sql,select,join,Mysql,Sql,Select,Join,或 我认为第一个更好,但我仍在学习如何编写更好的SQL语句。我不清楚在这种情况下,如何使一个语句优于另一个语句 如果有比我写的两种方式更好的方式,请告诉我。谢谢 编辑: 有老师和学生。他们在任何给定班级中作为学生或教师的位置可通过查看班级用户表找到。我想做的是,当给一个用户时,找到他是老师的班级,然后返回这些班级中的所有学生 以下是我的数据库模式: SELECT u.users_username, u.givenname, u.familyname, u.studentassent, u.par

我认为第一个更好,但我仍在学习如何编写更好的SQL语句。我不清楚在这种情况下,如何使一个语句优于另一个语句

如果有比我写的两种方式更好的方式,请告诉我。谢谢

编辑: 有老师和学生。他们在任何给定班级中作为学生或教师的位置可通过查看班级用户表找到。我想做的是,当给一个用户时,找到他是老师的班级,然后返回这些班级中的所有学生

以下是我的数据库模式:

SELECT u.users_username, u.givenname, u.familyname, u.studentassent, u.parentconsent, u.birthdate, u.gender
FROM users AS u
WHERE u.users_username
IN (
    SELECT c.users_username
    FROM classes_users as c
    JOIN classes_users as x
    ON c.classes_id = x.classes_id
    WHERE x.users_username = "johnny" AND x.role = "teacher"
)

第一个更好,假设
(classes\u id,users\u username)
是唯一的

MySQL
无法使用内部查询前导进行半联接(构造中的
)。因此
查询中的
将始终使用
用户
作为前导表,而对于
联接
查询,优化器可以选择前导表


如果
(classes\u id,users\u username)
不是唯一的,则查询在语义上是不等价的。您需要将
DISTINCT
添加到join查询中。

请发布您的模式和您试图实现的目标的描述。如果我理解正确的话,您是在试图为一个名为johnny的用户提取信息,该用户的角色是教师?我想我们可以提出一些模式改进建议。此外,在这种情况下,连接总是优于子查询。此外,这篇文章可能更适合codereview.stackexchange.comI。为了清晰起见,我添加了一个数据库架构。为了清晰起见,我添加了一个数据库架构。@user594044:在
类\u用户(用户\u用户名,角色)
上创建一个复合索引,只需使用第一个查询即可。
SELECT u.users_username, u.givenname, u.familyname, u.studentassent, u.parentconsent, u.birthdate, u.gender
FROM users AS u
WHERE u.users_username
IN (
    SELECT c.users_username
    FROM classes_users as c
    JOIN classes_users as x
    ON c.classes_id = x.classes_id
    WHERE x.users_username = "johnny" AND x.role = "teacher"
)
-- -----------------------------------------------------
-- Table `kcptech`.`users`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `kcptech`.`users` (
`users_username` VARCHAR(63) NOT NULL ,
`password` VARCHAR(255) NULL DEFAULT NULL ,
`salt` VARCHAR(127) NULL DEFAULT NULL ,
`givenname` VARCHAR(96) NULL DEFAULT NULL ,
`familyname` VARCHAR(128) NULL DEFAULT NULL ,
`privileges` TINYINT NULL DEFAULT NULL ,
`studentassent` TINYINT(1) UNSIGNED NULL DEFAULT NULL ,
`parentconsent` TINYINT(1) UNSIGNED NULL DEFAULT NULL ,
`birthdate` DATE NULL DEFAULT NULL ,
`gender` VARCHAR(1) NULL DEFAULT NULL ,
`registration` TIMESTAMP NULL DEFAULT NULL ,
PRIMARY KEY (`users_username`) ,
UNIQUE INDEX `uname_UNIQUE` (`users_username` ASC) )
ENGINE = InnoDB;




-- -----------------------------------------------------
-- Table `kcptech`.`classes`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `kcptech`.`classes` (
`classes_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`course` VARCHAR(127) NULL ,
`period` VARCHAR(31) NULL DEFAULT '' ,
`organization` VARCHAR(127) NULL DEFAULT '' ,
PRIMARY KEY (`classes_id`) ,
UNIQUE INDEX `id_UNIQUE` (`classes_id` ASC) )
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `kcptech`.`classes_users`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `kcptech`.`classes_users` (
`classes_id` INT UNSIGNED NOT NULL ,
`users_username` VARCHAR(64) NOT NULL ,
`role` VARCHAR(12) NOT NULL ,
PRIMARY KEY (`classes_id`, `users_username`) ,
INDEX `fk_class_users__users_users_username` (`users_username` ASC) ,
INDEX `fk_class_users__class_class_id` (`classes_id` ASC) ,
CONSTRAINT `fk_class_users__users_users_username`
  FOREIGN KEY (`users_username` )
  REFERENCES `kcptech`.`users` (`users_username` )
  ON DELETE NO ACTION
  ON UPDATE NO ACTION,
CONSTRAINT `fk_class_users__class_class_id`
  FOREIGN KEY (`classes_id` )
  REFERENCES `kcptech`.`classes` (`classes_id` )
  ON DELETE NO ACTION
  ON UPDATE NO ACTION)
ENGINE = InnoDB;