SELECT DISTINCT
u.username AS 用户名,
p.project_name AS 项目名称
FROM
Users u
JOIN
Projects p ON u.user_id = p.principal_investigator_id;
二、根据项目名称进行模糊查询,模糊查询要进行索引,需要给出explain语句
sql复制代码
EXPLAIN SELECT project_id, project_name
FROM Projects
WHERE project_name LIKE '%三国%';
三、统计用户的项目信息,查询所有用户的项目数量,并进行倒序排列
sql复制代码
SELECT
u.username AS 用户名,
COUNT(p.project_id) AS 项目数量
FROM
Users u
LEFT JOIN
Projects p ON u.user_id = p.principal_investigator_id
GROUP BY
u.user_id, u.username
ORDER BY
项目数量 DESC;
复杂查询
一、查询用户的基本信息,项目信息
sql复制代码
SELECT
u.user_id,
u.username,
u.gender,
u.email,
p.project_id,
p.project_name,
p.project_description,
p.start_date,
p.end_date,
p.status
FROM
Users u
LEFT JOIN
Projects p ON u.user_id = p.principal_investigator_id;
二、查看项目中项目阶段最多的项目对应的类型
sql复制代码
SELECT
p.project_name,
p.status
FROM
Projects p
WHERE
(SELECT COUNT(*)
FROM Projects p2
WHERE p2.status = p.status) =
(SELECT MAX(cnt)
FROM (SELECT status, COUNT(*) as cnt
FROM Projects
GROUP BY status) as subquery);
三、查询项目最多的用户,并且查询用户的全部信息与当前项目阶段
sql复制代码
SET @MostProjectsUserId = (
SELECT principal_investigator_id
FROM Projects
GROUP BY principal_investigator_id
ORDER BY COUNT(*) DESC
LIMIT 1
);
SELECT
u.*,
p.project_id,
p.project_name,
p.status AS current_project_status
FROM
Users u
JOIN
Projects p ON u.user_id = p.principal_investigator_id
WHERE
u.user_id = @MostProjectsUserId;
触发器
触发器一:确保在Projects表中插入新项目时,主研人必须是已存在的用户
sql复制代码
DELIMITER //
CREATE TRIGGER trg_check_principal_investigator
BEFORE INSERT ON Projects
FOR EACH ROW
BEGIN
IF NOT EXISTS (SELECT 1 FROM Users WHERE user_id = NEW.principal_investigator_id) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'The principal investigator does not exist.';
END IF;
END //
DELIMITER ;
-- 测试语句
INSERT INTO Projects (project_name, project_description, principal_investigator_id, start_date, end_date, status)
VALUES ('新项目测试', '测试项目描述', 999, '2023-05-01', '2023-12-31', '申请中'); -- 假设999是一个不存在的用户ID
-- 预期会失败,因为用户ID 999 不存在
-- 成功的测试语句
INSERT INTO Projects (project_name, project_description, principal_investigator_id, start_date, end_date, status)
VALUES ('新项目测试成功', '测试项目描述成功', 2, '2023-05-01', '2023-12-31', '申请中'); -- 假设用户ID 2 是存在的(孙悟空)
-- 检查新项目是否成功插入
SELECT * FROM Projects WHERE project_name = '新项目测试成功';
触发器二:在插入新的项目日志时,自动设置日志日期为当前时间(如果未提供)
sql复制代码
DELIMITER //
CREATE TRIGGER trg_set_log_date_if_null
BEFORE INSERT ON ProjectLogs
FOR EACH ROW
BEGIN
IF NEW.log_date IS NULL THEN
SET NEW.log_date = NOW();
END IF;
END //
DELIMITER ;
-- 测试语句
INSERT INTO ProjectLogs (project_id, user_id, log_content) VALUES
(2, 2, '项目申请已被接收');
-- 检查触发器是否工作
SELECT * FROM ProjectLogs WHERE log_content = '项目申请已被接收';
DELIMITER //
CREATE TRIGGER trg_check_project_status_update
BEFORE UPDATE ON Projects
FOR EACH ROW
BEGIN
IF NEW.status NOT IN ('申请中', '审批中', '执行中', '结题') THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid project status!';
END IF;
END //
DELIMITER ;
-- 测试语句(确保成功)
UPDATE Projects SET status = '审批中' WHERE project_id = 2; -- 将西游记文化研究的状态更改为审批中,应该成功
-- 检查Projects表,确保状态已更新
SELECT * FROM Projects WHERE project_id = 2;
存储过程
存储过程 1: 添加新用户
sql复制代码
DELIMITER //
CREATE PROCEDURE AddUser(IN p_username VARCHAR(50), IN p_password VARCHAR(255), IN p_gender ENUM('男', '女'), IN p_email VARCHAR(100))
BEGIN
INSERT INTO Users (username, password, gender, email)
VALUES (p_username, p_password, p_gender, p_email);
END //
DELIMITER ;
-- 测试语句
CALL AddUser('刘备', '123', '男', 'liubei@example.com');
-- 验证新用户是否添加成功
SELECT * FROM Users WHERE username = '刘备';
存储过程 2: 分配用户角色
sql复制代码
DELIMITER //
CREATE PROCEDURE AssignUserRole(IN p_user_id INT, IN p_role_id INT)
BEGIN
INSERT INTO UserRoles (user_id, role_id)
VALUES (p_user_id, p_role_id);
END //
DELIMITER ;
-- 测试语句
CALL AssignUserRole(3, 2); -- 假设林黛玉(user_id=3)需要被分配为项目负责人(role_id=2)
-- 验证角色是否分配成功
SELECT * FROM UserRoles WHERE user_id = 3;
存储过程 3: 记录项目日志
sql复制代码
DELIMITER //
CREATE PROCEDURE RecordProjectLog(IN p_project_id INT, IN p_user_id INT, IN p_log_content TEXT)
BEGIN
INSERT INTO ProjectLogs (project_id, user_id, log_date, log_content)
VALUES (p_project_id, p_user_id, NOW(), p_log_content);
END //
DELIMITER ;
-- 测试语句
CALL RecordProjectLog(1, 2, '项目有新的研究进展'); -- 假设为三国历史研究项目(project_id=1)添加日志,由孙悟空(user_id=2)记录
-- 验证日志是否记录成功
SELECT * FROM ProjectLogs WHERE project_id = 1 AND log_content LIKE '%项目有新的研究进展%';