数据库数据查询之嵌套查询与集合查询

由于 SQL 查询的种类繁多,这变得很复杂,但实际上非常简单。
我们先来说说最重要的事情。
对于1 9 岁以下或者计算机系学生的查询,可以这样写:
sql 选择学号、姓名 学生人数 其中年龄 <= 1 9 或部门 =“计算机科学系”;
还有一点,如果需要返回一个值,比如查询某个条件下的记录条数,可以这样做:
sql SELECT COUNT() AS 学生总数 学生人数 其中年龄 <= 1 9 或部门 =“计算机科学系”;
还有一个非常重要的细节。
如果你想使用子查询,例如返回一个值,你可以这样做:
sql SELECT COUNT() AS 学生总数 学生人数 学号在哪里(从学生年龄 <= 1 9 或院系=“计算机科学系”中选择学号);
我最初以为子查询只能用于返回一组值,但后来我发现它们也可以用于返回单个值,只要子查询的结果集是单个列即可。
等等,还有别的事。
如果需要使用“Not Found”来查询不符合条件的记录,可以这样做:
sql 选择学号、姓名 学生人数 如果不存在(从年龄 <= 1 9 或部门 =“计算机系”且学号 = 学号的学生中选择 1 );
很多人没有注意到这一点。
事实上,NOT EXISTS 可用于查询外部查询中不存在的记录。
我认为值得一试,因为这样可以避免使用复杂的JOIN操作。

子查询嵌套方法?——复杂查询处理

说实话,刚开始学习SQL的时候,嵌套子查询让我很头疼。
当时我看着这道复杂的题,脑子里嗡嗡作响,感觉就像是在解一道数学题,肯定是错的。
但是,用了很多次之后,我发现这个东西挺有趣的,就像搭积木一样,一步步为你摇出信息。

首先说一个他在群里遇到的真实案例。
有一次,老板让我们找到销量第一高的产品,但它不仅高,而且比所有产品的平均销量还要高。
我当时的第一个行动是,好吧,写AVG(SalesAmount)不就够了吗?为此,导师指出,如果要进行动态比较,必须使用子查询。
于是我写了这句话:
sql 选择产品名称、销售额 来自产品 WHERE SalesAmount>(从产品中选择 AVG(SalesAmount));
说实话,当我写完的时候,我还是很兴奋的。
我感觉我已经解决了这个难题。
这个搜索完美的用在WHERE子句中,将子查询得到的平均销量作为外查询的过滤条件。
这种场景特别适合,例如,如果您想检查某个值是否在某个集合中,或者需要动态地将其与某个值进行比较。

后来他遇到了更复杂的事情。
我们曾经不得不筛选掉工资高于同类平均工资的员工。
看问题,你觉得够CONNECTED吗? sed tunc non valde bene valebam,sic adhuc scripsi subquero:
sql。
选择员工姓名、工资 来自 * 的员工 凡商户>( 从员工中选择平均(工资),其中 DepartmentID = e.DepartmentID ); 这就是为什么它跑得像蜗牛一样慢。
导师看到后笑了,说,你看,这些子查询都连接到一个典型的标题上。
外部查询的每一行都必须通过内部子查询运行。
Cogita de eo,si in tabula notitiarum 1 00,000 nummorum sint,subqueratio Interior 1 00,000 vicibus exsecuta erit。
我当时很尴尬。
信息量巨大,写作过程简直恐怖。

后来我意识到在这种情况下,重写它会比 JOIN 或 CTE(公用表表达式)好得多。
很可能用这样的 JOIN 重写它:
sql SELECT e.EmployeeName、e.Salary 来自 * 的员工 加入( SELECT DepartmentID, AVG(Salary) AS AvgDeptSalary 来自员工 按部门 ID 分组 ) AS dept_avg DE e.DepartmentID = dept_avg.DepartmentID WHERE e.Salary> dept_avg.AvgDeptSalary;
或者使用CTE:
sql 在 DeptAvg AS ( 选择部门 ID、平均(薪资)AS AvgDeptSalary 来自员工 按部门 ID 分组 ) SELECT e.EmployeeName、e.Salary 来自 * 的员工 JOIN DeptAvg d FROM e.DepartmentID = d.DepartmentID WHERE e.Salary> d.AvgDeptSalary; 这两种写法一般都比较好被数据库优化器处理,避免子查询的重复执行。
这节课给我留下了深刻的印象。
每次写SQL的时候,我都要提醒自己,如果使用多个连接子查询的话,性能真的会很糟糕。

谈论 select 子句中的标量子查询。
我用它来计算每个客户的订单总数。
当时客户表和订单表没有直接关系,但我想在客户名称旁边添加订单号。
我使用了标量查询:
sql 选择客户名称, (SELECT COUNT (OrderID) FROM ORDER o WHERE o.CustomerID = c.CustomerID) AS TotalOrders 来自客户 c;
这个书写系统很短。
虽然可能不如链接那么好,但是比简单的写法还是差了一些。
适合只需要添加相关数据列而不需要进行复杂JOIN的场景。

总的来说,如果使用得当,子查询嵌套确实很方便,并且可以将复杂的逻辑分解为一步一步的步骤。
但如果你用得不好,特别会被研究不足连接起来,性能问题确实令人担忧。
因此,写SQL应该像做饭一样。
显然你需要使用盐和糖。
他们不会随意添加香料。
最后的味道肯定会出错。
虽然 CONNECT 有时写起来并不那么直观,但它的性能一般比较稳定,尤其是在处理大量数据时。
关键取决于你想做什么,是过滤数据还是合并数据,做之前你会先想一想。