MySQL基础:在多张表格中检索数据


多表合并,依据主表和根据主表和连接表的属性相关性来生成新的关系表格。(可重复的并集)

1. 内连接

各表分开存放是为了保证最下实体单元内的属性联系更加紧密,但是优势需要将相互之间的关系连接,从而满足多表间的查询要求。如果两个关系之间有相同的属性,则可以用内连接将两个表合并。
虽然SELECT语句还是放在前面,但是我们写语句时从后往前看,假定已经将两个关系合并过了来操作SELECT语句。
NOTE:

  • AS 也可以用来设置简化的别名,同时AS可省略。一旦用别名,所有地方都需要使用别名。
  • 选择关系中相同的属性列时,必须指定关系表名前缀,不然会报错。良好的编程习惯是:明确属性不加前缀,不明确前加表名前缀。
  • 编写SELECT的列时,可以先用*,确定好别名和需要选择的属性列后,再修改SELECT中选定的列名。
  • 合并完后的表格,一般需要设置排序规则。
SELECT o.order_id, c.customer_id, c.first_name, c.last_name
-- 列前尽量加上表名前缀
FROM orders o  -- 创建别名,省略AS
JOIN customers c
    ON o.customer_id = c.customer_id
ORDER BY o.order_id ASC

2. 跨数据库连接

只需要在不属于当前数据库的表前面加上数据库名前缀即可。
USE关键字可以将操作转移到某个数据库,而.字符可以跨数据库访问表

USE sql_store;
SELECT *
FROM order_items  oi
JOIN sql_inventory.products  sp
    ON oi.product_id = sp.product_id

3. 自连接

自连接和内连接的区别在于,内连接用的是两个不同的表,自连接用的是相同的表(表内属性列有相同属性数值),然后取不同的别名。都是采用相同的属性值连接起来。

USE sql_hr;
SELECT e.employee_id, e.first_name employee, m.first_name manager
FROM employees e 
JOIN employees m 
	ON e.reports_to = m.employee_id

4. 多表连接

一个主表采用FROM xxx 后面重复使用JOIN table ON attribute语句。

USE sql_store;
SELECT o.order_id, o.order_date, c.first_name, os.name
FROM orders o
JOIN customers c
    ON o.customer_id = c.customer_id
JOIN order_statuses os
    ON o.status = os.order_status_id
-- ORDER BY o.order_id

NOTE:选择合适的列输出,保证输出的数据不凌乱(编程时再处理,先是全部选取*)。

5. 复合连接条件

软件中属性码前黄色闪电表示为主码(候选码),复合主键

对于复合主键,即候选码,需要采用所有的候选码的属性来进行连接两个表格。

USE sql_store;
SELECT *
FROM order_items oi
JOIN order_item_notes oin
    ON oi.order_id = oin.order_id
AND oi.product_id = oin.product_id – 该查询程序运行出来无满足要求的结果
/* USING (order_id, product_id)*/

6. 隐式连接语法

用FROM WHRER 来替代 FROM JOIN ON,但是尽量不要用隐式连接。因为如果忘记用关键词WHERE将产生“交叉连接”,两个10条记录的表格将产生100条记录新表格。

SELECT *
FROM orders o, customers c
WHERE o.customer_id = c.customer_id
/*JOIN customers c
    ON o.customer_id = c.customer_id*/

7. 外连接

  • (INNER) JOIN 结果只包含两表的交集,注意“广播(broadcast)”效应,根据多列出的有重复的属性记录数值会进行扩充
  • LEFT/RIGHT (OUTER) JOIN 结果里除了交集,还包含只出现在左/右表中的记录.左连接则包含主表全部信息,右连接则包含连接的表全部信息,没有连接的属性数值则用NULL进行填充。尽量少使用右连接RIGHT JOIN
  • 连接过程涉及记录数据互补的问题
SELECT o.order_id, o.order_date, c.customer_id, c.first_name
FROM orders o
RIGHT JOIN customers c
	ON o.customer_id = c.customer_id

8. 多表外连接

与内连接的多表连接类似,尽量不用RIGHT JOIN;
内连接和外连接可以混合使用。

SELECT o.order_date, order_id, c.first_name customer, s.name shipper, os.name
FROM orders o
JOIN customers c
    ON o.customer_id = c.customer_id
LEFT JOIN shippers s   -- 外连接的作用域大于内连接
    ON o.shipper_id = s.shipper_id
JOIN order_statuses os     -- 只要相关联,以多的数据为准
-- 内连接中,不同表中有没有关联的记录则不表示出来
    ON o.status = os.order_status_id

9. 自外连接

自连接和外连接的综合使用

USE sql_hr;
SELECT e.employee_id, e.first_name employee, m.first_name manager
FROM employees e
LEFT JOIN employees m
    ON e.reports_to = m.employee_id  
    -- 根据主表条件来确定连接表的记录数值内容

10. USING子句

当作为合并条件 join condition 的列在两个表中有相同列名时,可用 USING (……, ……) 取代 ON …… AND …… 予以简化,内/外连接均可如此简化。(复合连接即候选码,则USING的(内部采用逗号隔开即可))

NOTE:
1)USING对复合主键的简化效果更加明显;
2)相同属性对应的不同列名必须采用ON…

USE sql_store;
SELECT o.order_id, c.first_name customer, s.name shipper
FROM orders o
JOIN customers c
    -- ON o.customer_id = c.customer_id
    USING (customer_id)
LEFT JOIN shippers s
    USING (shipper_id)

11. 自然连接

NATURAL JOIN 就是让MySQL自动检索同名列作为合并条件。但是不建议使用,因为有时会产生意想不到的不可控的结果。

USE sql_store;
SELECT o.order_id, c.first_name customer
FROM orders o
NATURAL JOIN customers c

12. 交叉连接

CROSS JOIN得到两个表记录排列组合(两个表中的记录两两相互连接)后的所有记录情况,不需要合并条件(任何两个表都可以交叉连接,但是内连接和外连接不是任意两个表就可以连接的)。内连接和外连接产生的结果为交叉连接产生的结果的子集。

NOTE:隐式内合并忽略 WHERE 子句(即合并条件)的情况,交叉连接的隐式表达也就是把 CROSS JOIN 改为逗号,即 FROM A CROSS JOIN B 等效于 FROM A, B,更推荐显式语法,因为更清晰

USE sql_store;
SELECT o.order_id, c.first_name customer
FROM orders o
CROSS JOIN customers c
-- FROM orders o, customers c
ORDER BY o.order_id

13. 联合

FROM …… JOIN …… 可对多张表进行横向列合并,而 …… UNION …… 可用来按行纵向合并多个查询结果,这些查询结果可能来自相同或不同的表.

  • 同一张表可通过UNION添加新的分类字段,即先通过分类查询并添加新的分类字段再UNION合并为带分类字段的新表。
  • 不同表通过UNION合并的情况如:将一张18年的订单表和19年的订单表纵向合并起来在一张表里展示.

NOTE:
1)合并的查询结果必须列数相等,否则会报错;
2)合并表里的列名由排在UNION前面的决定。

SELECT 
    order_id,  
    order_date, 
    'Active' AS status
FROM orders
WHERE order_date >= '2019-01-01'
UNION
SELECT 
    order_id,  
    order_date, 
    'Archived' AS status
FROM orders
WHERE order_date < '2019-01-01'
SELECT first_name
FROM customers
UNION
SELECT name
FROM shippers
  • 15
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 MySQL ,可以使用以下方法来禁止删除表格数据: 1. 使用触发器:可以在删除数据时触发触发器,在触发器编写逻辑来阻止数据被删除。例如: ``` CREATE TRIGGER no_delete BEFORE DELETE ON tablename FOR EACH ROW BEGIN SELECT 'You are not allowed to delete rows from this table' AS message; END ``` 2. 使用存储过程:可以在删除数据时调用存储过程,在存储过程编写逻辑来阻止数据被删除。例如: ``` CREATE PROCEDURE no_delete (IN p_id INT) BEGIN SELECT 'You are not allowed to delete rows from this table' AS message; END ``` 然后在执行 DELETE 语句时调用存储过程: ``` DELETE FROM tablename WHERE id = 1; ``` 3. 使用视图:也可以使用视图来禁止删除表格数据。视图是一种虚拟表,它不存储数据,而是将数据从其他表格检索出来。因此,可以创建视图来检索数据,但是不能删除数据。例如: ``` CREATE VIEW v_tablename AS SELECT * FROM tablename; ``` 然后,在执行 DELETE 语句时使用视图名称: ``` DELETE FROM v_tablename WHERE id = 1; ``` 这将导致错误,因为无法在视图删除数据。 4. 使用权限管理:可以使用 MySQL 的权 ### 回答2: 要禁止删除MySQL表格数据,可以采取以下几种方法: 1. 使用权限控制:通过为用户分配合适的权限,限制其对表格的删除操作。可以使用GRANT语句给予用户SELECT和INSERT权限,但不赋予DELETE权限,这样用户就无法删除表格数据。 示例代码: GRANT SELECT, INSERT ON database.table TO 'user'@'host'; 2. 使用数据库触发器:创建一个BEFORE DELETE触发器,用于捕捉删除操作,并阻止其执行。在触发器,可以通过抛出一个异常来终止删除操作,从而阻止数据的删除。 示例代码: CREATE TRIGGER prevent_delete BEFORE DELETE ON database.table FOR EACH ROW BEGIN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Deleting data from this table is not allowed!'; END; 3. 使用备份和恢复策略:定期备份MySQL数据库,并确保备份文件的安全性。在需要恢复数据时,从备份文件还原表格,以避免意外删除数据所带来的损失。 以上是一些常用的方法来禁止删除MySQL表格数据。根据实际需求和系统环境,可以选择适合的方法来保护数据的完整性和安全性。 ### 回答3: 要禁止删除MySQL表格数据,可以通过以下方法实现: 1. 限制用户权限:可以通过修改用户的权限来禁止其删除表格数据。在MySQL,可以使用GRANT和REVOKE语句来授予或撤销用户的权限。例如,可以使用REVOKE DELETE权限来禁止用户删除表格数据。 2. 使用强制删除警告:可以通过在删除操作前添加确认弹窗或强制输入密码等措施来提醒用户。这样的措施可以增加删除操作的可见性,并防止意外删除。 3. 设置触发器:可以在MySQL表格创建触发器,监控删除操作,并在删除时执行特定动作。可以使用BEFORE DELETE触发器来取消删除操作,或使用AFTER DELETE触发器来记录删除操作的详细信息,以提供审核和追踪。 4. 数据库备份和恢复:可以定期对MySQL数据库进行备份,并设置合适的恢复策略。这样即使误删了数据库数据,也可以通过数据库备份来进行恢复,保证数据的完整性。 总结起来,禁止删除MySQL表格数据需要从权限控制、数据删除操作的提示和验证、触发器和数据备份恢复等多个方面来实施。每一种方法都可以根据具体情况的不同进行深入的配置和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值