gpt4 book ai didi

mysql - 这个 SELECT 应该使用连接还是子查询?

转载 作者:行者123 更新时间:2023-11-29 01:31:36 24 4
gpt4 key购买 nike

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

或者

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"
)

我认为第一个更好,但我仍在学习如何编写更好的 SQL 语句,我不清楚在这种情况下使一个语句比另一个更好的所有内部结构。

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

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

这是我的数据库架构:

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

最佳答案

第一个更好,假设 (classes_id, users_username) 是唯一的。

MySQL 无法使用内部查询前导进行半连接(IN 构造)。所以 IN 查询将始终使用 users 作为前导表,而对于 JOIN 查询,优化器可以选择前导表。

如果 (classes_id, users_username) 不是唯一的,则查询在语义上是不等价的。您需要将 DISTINCT 添加到连接查询中。

关于mysql - 这个 SELECT 应该使用连接还是子查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10693895/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com