SQL专项训练-第四天 (组合查询 & 指定选取)
题目类型:组合查询 & 指定选取
难度:简单
第一题:1965. 丢失信息的雇员
-
题目链接:1965. 丢失信息的雇员
-
思路:
本题考查组合查询,关键字为union
,其作用是将多条select语句组合成一个结果集。
union的规则就是
- 必须由两条或两条以上的select语句组成,语句之间由union分隔。
- union中的每个查询必须包含相同的列、表达式或聚集函数。
- 列数据烈性必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的基本类型
如果要对组合查询的结果进行排序,就要在语句之后加上order by语句。
本题的思路就是在Employees表中找出在Salaries表中不存在的employee_id,作为一个select查询结果;
然后在Salaries表中找出Employees表中不存在的employee_id,作为凌晔哥查询结果;
然后将这两个select查询结果运用union并起来,然后用order by语句将结果从小到大排序输出。
- SQL语句:
select employee_id
from Employees
where employee_id not in (
select employee_id
from Salaries
)
union
select employee_id
from Salaries
where employee_id not in (
select employee_id
from Employees
)
order by employee_id;
第二题:1795. 每个产品在不同商店的价格
-
题目链接:1795. 每个产品在不同商店的价格
-
思路:
这一题最主要的思路是将列转为行,还是运用union操作,分别将从store1、store2和store3中查到的数据重新编排为列输出。 -
SQL语句:
select product_id, 'store1' as store, store1 as price from Products where store1 is not null
union all
select product_id, 'store2' as store, store2 as price from Products where store2 is not null
union all
select product_id, 'store3' as store, store3 as price from Products where store3 is not null
order by product_id asc;
第三题:608. 树节点
-
题目链接:608. 树节点
-
思路:
本题由三个查询语句构成分别查询Root、Inner、Leaf;
满足节点为Root的条件是:该节点的父节点为null;
满足节点为Inner的条件是:该节点在id中有且在p_id中也有,并且这个id的父节点不能为null
满足节点为Leaf的条件是:该节点没在p_id中出现 -
SQL语句:
select id, 'Root' as type
from tree
where p_id is null
union
select id, 'Inner' as type
from tree
where id in (
select p_id
from tree
) and p_id is not null
union
select id, 'Leaf' as type
from tree
where id not in (
select distinct p_id
from tree
where p_id is not null # 这个where很容易忘写哦
# union
# select id
# from tree
) and p_id is not null
order by id;
第四题:176. 第二高的薪水
-
题目链接:176. 第二高的薪水
-
思路:
运用limit进行限制,思路是:先将工资表由高到低排序输出,然后用limit语句进行限制;
这里先举几个例子:
limit 5
表示指示mysql返回最多不超过五行;
limit 5,5
表示指示mysql返回从第五行开始的五行。第一个数为开始位置,第二个数为要检索的行数。
MySql 5中limit的用法:
在MySql 5中limit还支持一种写法:
limit 4 offset 3
表示从第3行开始取4行,也可以写作limit 3,4
。这两者表达的意思是一样的。
换做本题,我们要返回第二高的工资,就要从第一行开始取,取一个(因为行数是从0开始的,所以第二高的工资在第一行),就是第二高的工资。
根据前面的讲述,这里有两种写法:limit 1 offset 1
和limit 1,1
,这两种都可以;
因为在表中有可能数据量不够2个,这样就要返回null
,所以我们将第一个select查询当成一个临时表,在临时表中再查一次,就行了。 -
SQL语句:
SELECT
(SELECT DISTINCT
Salary
FROM
Employee
ORDER BY Salary DESC
LIMIT 1 OFFSET 1) AS SecondHighestSalary
;