SELECT 客户.公司名称, ROUND(SUM(订单明细.单价 * 订单明细.数量 * (1 - 订单明细.折扣)), 2) AS 订单总额 FROM 客户,订单,订单明细 where 客户.客户ID = 订单.客户ID && 订单.订单ID = 订单明细.订单ID && 客户.公司名称 LIKE '%人寿%' GROUP BY 客户.公司名称;
CREATE VIEW V_雇员销售总额 AS SELECT 姓名, SUM(销售总金额) AS 总销售金额 FROM V_雇员产品销售额 GROUP BY 姓名;
SELECT * FROM V_雇员销售总额;
DROP VIEW RESTRICT V_雇员产品销售额; DROP VIEW CASCADE V_雇员产品销售额;
4.3. 实验1.3 数据高级查询实验
4.3.1. 1.3.1列出购买了“小坊”供应的“干贝”的客户的公司名称。(要求分别使用连接查询和嵌套查询两种方式,并在 MySQL WorkBench 中比较这两种方式的执行计划:点击结果窗口右侧的“Execution Plan”按钮)。
--连接查询 SELECT 客户.公司名称 FROM 订单 JOIN 客户 ON 订单.客户ID = 客户.客户ID JOIN 订单明细 ON 订单.订单ID = 订单明细.订单ID JOIN 产品 ON 订单明细.产品ID = 产品.产品ID JOIN 供应商 ON 产品.供应商ID = 供应商.供应商ID WHERE 供应商.公司名称 = '小坊' AND 产品.产品名称 = '干贝';
嵌套查询: SELECT 客户.公司名称 FROM 客户 WHERE EXISTS ( SELECT 1 FROM 订单 JOIN 订单明细 ON 订单.订单ID = 订单明细.订单ID JOIN 产品 ON 订单明细.产品ID = 产品.产品ID JOIN 供应商 ON 产品.供应商ID = 供应商.供应商ID WHERE 供应商.公司名称 = '小坊' AND 产品.产品名称 = '干贝' AND 订单.客户ID = 客户.客户ID );
SELECT COUNT(*) FROM 客户 WHERE NOT EXISTS ( SELECT 1 FROM 订单 JOIN 订单明细 ON 订单.订单ID = 订单明细.订单ID JOIN 产品 ON 订单明细.产品ID = 产品.产品ID JOIN 供应商 ON 产品.供应商ID = 供应商.供应商ID WHERE 供应商.公司名称 = '小坊' AND 产品.产品名称 = '干贝' AND 订单.客户ID = 客户.客户ID );
SELECT 客户.公司名称 FROM 客户 WHERE EXISTS ( SELECT 1 FROM 订单 JOIN 订单明细 ON 订单.订单ID = 订单明细.订单ID JOIN 产品 ON 订单明细.产品ID = 产品.产品ID WHERE 订单.客户ID = 客户.客户ID AND EXISTS ( SELECT 1 FROM 订单 AS 订单2 JOIN 订单明细 AS 订单明细2 ON 订单2.订单ID = 订单明细2.订单ID WHERE 订单2.客户ID = (SELECT 客户ID FROM 客户 WHERE 公司名称 = '森通') AND 订单明细2.产品ID = 产品.产品ID AND 产品.类别ID = 3 ) );
4.3.4. 1.3.4采用 FROM 子句中的嵌套查询方式列出订单平均金额超过 800 元的华北地区客户的公司名称及订单平均金额,要求输出结果按照平均金额从低到高排序。
SELECT 公司名称, 平均订单金额 FROM ( SELECT 客户.公司名称, AVG(订单总金额) AS 平均订单金额 FROM ( SELECT 订单.客户ID, SUM(订单明细.数量 * 产品.单价) AS 订单总金额 FROM 订单 JOIN 订单明细 ON 订单.订单ID = 订单明细.订单ID JOIN 产品 ON 订单明细.产品ID = 产品.产品ID GROUP BY 订单.客户ID ) AS 订单总金额 JOIN 客户 ON 订单总金额.客户ID = 客户.客户ID WHERE 客户.地区 = '华北' GROUP BY 客户.公司名称 ) AS 订单平均金额 WHERE 平均订单金额 > 800 ORDER BY 平均订单金额;
-- 创建新的客户表“河北客户” CREATE TABLE 河北客户 AS SELECT * FROM 客户 WHERE 城市 = '石家庄';
-- 把秦皇岛客户加入到“河北客户”表中 INSERT INTO 河北客户 SELECT * FROM 客户 WHERE 城市 = '秦皇岛'; SELECT * FROM 河北客户;
-- 创建一个“购物统计”表,记录每个客户的公司名称及其订单总价 CREATE TABLE 购物统计 AS SELECT 客户.公司名称, ROUND(SUM(订单明细.单价*订单明细.数量*(1-订单明细.折扣)), 2) AS 订单总价 FROM 订单,客户,订单明细 WHERE 客户.客户ID = 订单.客户ID && 订单.订单ID = 订单明细.订单ID GROUP BY 公司名称;
-- 在订单表中增加一个类型为 Decimal(8, 2)的属性“总金额” ALTER TABLE 订单 ADD 总金额 decimal(8,2);
-- 利用订单明细表中的属性修改订单表中的总金额:总金额 = 单价*数量*(1-折扣) UPDATE 订单 SET 总金额 = (SELECT SUM(单价*数量*(1-折扣)) FROM 订单明细 WHERE 订单.订单ID = 订单明细.订单ID);
4.5.6. 1.5.6DELETE 语句(删除给定条件的所有记录)删除客户“东南实业”的所有订单(先删订单明细,再删订单)。只删除客户“三川实业有限公司”的所有订单,而不先删除其明细,看看结果如何?将“订单明细”的外码约束“订单明细_ibfk_1”修改为级联删除(使用 ALTER Table命令对约束先删再增);现在直接删除客户“三川实业有限公司”的所有订单,看看结果如何?
DELETE FROM 订单明细 WHERE 订单ID IN ( SELECT 订单ID FROM 订单 WHERE 客户ID = (SELECT 客户ID FROM 客户 WHERE 公司名称 = '东南实业') );
DELETE FROM 订单 WHERE 客户ID = (SELECT 客户ID FROM 客户 WHERE 公司名称 = '东南实业');
DELETE FROM 订单 WHERE 客户ID = (SELECT 客户ID FROM 客户 WHERE 公司名称 = '三川实业有限公司');
ALTER TABLE 订单明细 DROP FOREIGN KEY 订单明细_ibfk_1;
ALTER TABLE 订单明细 ADD CONSTRAINT 订单明细_ibfk_1 FOREIGN KEY (订单ID) REFERENCES 订单(订单ID) ON DELETE CASCADE;
DELETE FROM 订单 WHERE 客户ID = (SELECT 客户ID FROM 客户 WHERE 公司名称 = '三川实业有限公司');
SQL> CREATE USER 张颖 IDENTIFIED BY '123456'; SQL> CREATE ROLE 销售代表; SQL> GRANT select ON northwind.销售视图 TO 销售代表; SQL> GRANT 销售代表 TO 张颖;
SQL> set default role all to 张颖;
4.6.8. 1.6.8在窗口 2 中以不同身份登录,验证以上视图;
--以张颖为例 SQL> SELECT Distinct 雇员ID FROM 销售视图;
4.6.9. 1.6.9收回用户“张颖”的“销售代表”角色权限,并验证之;
SQL> revoke 销售代表 from 张颖;
SELECT Distinct 雇员ID FROM 销售视图;
4.6.10. 1.6.10自己设计关于数据库和表的其他权限操作实验,并验证。
回收除root用户外其他所有用户的权限
-- 查询除 root 外的其他用户的列表 SELECT User, Host FROM mysql.user WHERE User != 'root';
mysql.infoschema,mysql.session 和 mysql.sys 是 MySQL 系统账户,不应该修改这些账户的权限。
--收回权限 REVOKE ALL PRIVILEGES ON *.* FROM '张颖'@'%'; REVOKE ALL PRIVILEGES ON *.* FROM '赵军'@'%'; REVOKE ALL PRIVILEGES ON *.* FROM '销售代表'@'%'; REVOKE ALL PRIVILEGES ON *.* FROM '销售经理'@'%';