做SQL或类SQL查询工作,跟GROUP BY打交道太频繁了,使用人士应该都晓得:在SELECT子句中出现的
字段或属性
,如果不是在聚合函数中,那就必须要放到GROUP BY子句里面去,反过来,没有出现在GROUP BY子句中的
字段或属性
,只能在聚合函数中。。。。。。
有时候,我们也需要对一个字段/属性作处理,假设有这样一个场景:在Hive数据库里有表my_table,my_table里有字段date, type,type可能取值为1, 2, 3, 4,还有可能出现其它异常值,如NULL;另外,此表还有用户ID字段user_id。
现在我们想要基于user_id,对不同的date和各种type去统计UV,并希望把type字段等于1或2统称为'A',等于3统称为'B',其它值统称为'未知'。
很快,数据出来了。
不对,怎么会相同date、相同my_type下产生了不同的几行?!
纠结于没报语法错误是没有用的,这样半天看不出破绽。
“一定是我打开的方式不对”!坚定了这个信念之后,果然如有神助,恍然大悟,要把select子句里的整个表达式也放到group by子句里!像酱紫:
当然,我们给某列取的别名不能被GROUP BY解析,这一点SQL或HQL倒是会进行报错提醒。
我承认,标红的文字是故意这样写的,为了突出这个“陷阱”的重要性。不过,理解能力好一点的童鞋,可能直接就能把想象延伸到表达式,根本就不会因为这个“陷阱”不会报语法错误而认为这是个陷阱呢。
知识这个东西,如果没有实际场景数据进行学习,从字面理解到实际掌握还是有距离的;有那么一些知识,始终还是要通过实际场景转化成为经验。
那么,由UDTF返回的字段或属性,必须放在GROUP BY子句中吗?有没有lateralview的关系?
有时候,我们也需要对一个字段/属性作处理,假设有这样一个场景:在Hive数据库里有表my_table,my_table里有字段date, type,type可能取值为1, 2, 3, 4,还有可能出现其它异常值,如NULL;另外,此表还有用户ID字段user_id。
现在我们想要基于user_id,对不同的date和各种type去统计UV,并希望把type字段等于1或2统称为'A',等于3统称为'B',其它值统称为'未知'。
一开始,我写成了这样:
select
`date`,
(
case type
when 1 or 2 then ‘A’
when 3 then ‘B’
else ‘未知’
end
) as my_type,
count(distinct user_id) as uv
from my_table
group by `date`, type
不错,跑起来了。
。。。。。。很快,数据出来了。
不对,怎么会相同date、相同my_type下产生了不同的几行?!
纠结于没报语法错误是没有用的,这样半天看不出破绽。
“一定是我打开的方式不对”!坚定了这个信念之后,果然如有神助,恍然大悟,要把select子句里的整个表达式也放到group by子句里!像酱紫:
select
`date`,
(
case type
when 1 or 2 then ‘A’
when 3 then ‘B’
else ‘未知’
end
) as my_type,
count(distinct user_id) as uv
from my_table
group by
`date`,
(
case type
when 1 or 2 then ‘A’
when 3 then ‘B’
else ‘未知’
end
)
当然,我们给某列取的别名不能被GROUP BY解析,这一点SQL或HQL倒是会进行报错提醒。
我承认,标红的文字是故意这样写的,为了突出这个“陷阱”的重要性。不过,理解能力好一点的童鞋,可能直接就能把想象延伸到表达式,根本就不会因为这个“陷阱”不会报语法错误而认为这是个陷阱呢。
知识这个东西,如果没有实际场景数据进行学习,从字面理解到实际掌握还是有距离的;有那么一些知识,始终还是要通过实际场景转化成为经验。
那么,由UDTF返回的字段或属性,必须放在GROUP BY子句中吗?有没有lateralview的关系?