问题①:HIVE有不等值连接吗?
问题②:not in 与not exists
问题③:查询连续登录连天的用户,并行成一行记录
问题④:查询工资排第4到第8位有几种方法
问题⑤:SQL的优化
-
有,Hive中,不等值连接的实现依赖于LEFT JOIN或RIGHT JOIN等连接操作符,并结合WHERE子句来实现。但使用不等值连接时会全表扫描,可能会影响效率。
-
not in:列表排除,直接从给定的列表中排除那些特定的值。比如“班级里不在[小明、小红、小刚]名单中的同学”。(不在其中)
not exists:去判断是不是根本不存在某个特定的关联,排除关系。(不存在某种关系) -
连续登陆问题:
思路分析:
对用户登录记录按照用户ID和登录日期进行排序。
使用ROW_NUMBER()函数为每个用户的登录记录分配一个序列号,序列号的分配依据是登录日期的先后顺序。
计算相邻登录记录之间的日期差异,如果这个差异为1,则表明这两个登录记录是连续的。
根据日期差异,筛选出连续登录的用户记录。
步骤
数据去重:由于同一用户可能在同一天内有多次登录记录,因此首先需要对登录记录进行去重处理,只保留每个用户每天的一条记录。
排序:使用ORDER BY语句对去重后的记录按照用户ID和登录日期进行排序。
分配序列号:使用ROW_NUMBER()函数为每个用户的登录记录分配序列号,序列号会随着日期依次递增。
计算日期差异:通过DATE_SUB()函数计算当前登录日期与前一登录日期的差异,如果这个差异为1,则认为这两个登录记录是连续的。减去间隔排序天数。
筛选连续登录记录:根据日期差异的结果,筛选出连续登录的用户记录。
代码补充:WITH t1 AS (
SELECT DISTINCT uid, date(login_time) ymd
FROM t_login),
t2 as (
select uid,ymd,row_number() over (partition by uid order by ymd) as ra,
date_sub(ymd,interval (row_number() over (partition by uid order by ymd)) day) sub_date
from t1)
select uid from t2
group by uid
having count(*)>=3 -
第一种:用窗口函数对工资进行排序,判断条件排序从4到8。SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num
FROM employees
) subquery
WHERE row_num BETWEEN 4 AND 8;
第二种;使用 LIMIT 和 OFFSET,对工资排序,跳过前面3行,取后续的5行。
SELECT *
FROM employees
ORDER BY salary DESC
LIMIT 5 OFFSET 3; -
sql的优化:加索引;语句优化,避免全表扫描,尽量用范围扫描,指定具体字段;
案例一:慢查询优化
针对慢查询,可以通过EXPLAIN分析查询执行计划,找到性能瓶颈所在,并根据分析结果调整查询语句或添加索引。
案例二:连接查询性能问题
对于连接查询性能问题,确保连接字段上有索引,并尽可能使用INNER JOIN替代其他类型的连接,因为INNER JOIN的性能通常更好。
案例三:子查询性能问题
子查询可能会导致性能问题,特别是在数据量较大时。可以考虑使用JOIN或临时表来重写查询,以避免子查询。
案例四:大批量插入或更新
在进行大批量数据操作时,应避免单个大事务,而是将其拆分为多个小事务进行处理,以减少锁的竞争和事务的冲突。
案例五:频繁的重复查询
对于频繁的重复查询,可以考虑使用缓存来减少数据库的负载,如使用内存缓存(如Redis)或者数据库缓存(如MySQL的查询缓存)。