如何用SQL来写动态SQL,本文主要是HiveQL

首先声明本人是初级程序员。


面临的问题:我们写的SQL中的很多需要改变的,比如where子句中=后面。静态的数据库改变又要重新写的SQL已经满足不了我们了。怎么才能写一个数据库内部数据变动,但是SQL不变的动态SQL呢?

本文最主要问题:

在Hive环境中怎么实现:编写一个HiveQL执行出来的结果是根据Hive数据仓库表中的数据动态生成我们所需要的静态的HiveQL.


动态SQL是什么,为什么要用它,怎么用它,在哪里用它?


动态SQL实际上就是静态SQL里面的一些字段需要经常替换,怎么替换呢?


把这个SQL拆分成几段,把经常需要替换的字段拆出来,相当于参数变量。那么问题又来了,用什么方法拆开?


这个问题有两种预先环境:

1.一种是在java语言或者其他的非直接执行sql语句的环境,相信这种都见过。JAVA中有很多方法可以把动态SQL中动的部分拆开,以方便替换。

2.还有就是在执行sql语句的环境中。其中比较常见的就是MYSQ提供的EXEC执行的存储过程和批处理。我们今天说的是在Hive仓库中执行的HiveQL。


这么多环境他们都分别用什么方法来拼接呢?(这里主要讨论第二种数据库环境)

有的时候,我们有需要将由不同栏位获得的资料串连在一起。每一种资料库都有提供方法来达到这个目的:
MySQL: CONCAT()
Oracle: CONCAT(), ||
SQL Server: +

想必我们都用过+。0.0

CONCAT(字串1, 字串2, 字串3, ...): 将字串1、字串2、字串3,等字串连在一起。
请注意,Oracle的CONCAT()只允许两个参数;
换言之,一次只能将两个字串串连起来。不过,在Oracle中,我们可以用'||'来一次串连多个字串。

举个例子1:

MySQL/Oracle:
SELECT CONCAT(region_name,store_name) FROM Geography
WHERE store_name = 'Boston';

结果:
'EastBoston'
例子2:
Oracle:
SELECT region_name || ' ' || store_name FROM Geography
WHERE store_name = 'Boston';

结果:
'East Boston'

例子3:

SQL Server:
SELECT region_name + ' ' + store_name FROM Geography
WHERE store_name = 'Boston';
结果:

'East Boston'

这些只是拼接。

本文重点来了:HiveQL支持哪种方法呢,又怎么实现动态呢

HiveQL:

HiveQL中||只是逻辑或OR的意思,不是字符串“连接”的意思,但是并且只支持函数concat(str1,str2,str3...)进行字符串拼接。接下来到了难点了,怎么写呢?希望自己好好想想在看我的答案:


下面是我的一个例子:

先看看我的基础数据表:

hive> SELECT * FROM testrecords;
OK
'20160412'      10      100
'20160413'      15      80
'20160414'      20      70
'20160415'      18      60
'20160416'      19      50
'20160417'      17      40
'20160418'      21      30
'20160419'      23      10
Time taken: 0.408 seconds, Fetched: 8 row(s)
下面是我的动态HQL语句及结果:

hive> select concat('select * from records where year = ',year) from testrecords;
OK
select * from records where year = '20160412'
select * from records where year = '20160413'
select * from records where year = '20160414'
select * from records where year = '20160415'
select * from records where year = '20160416'
select * from records where year = '20160417'
select * from records where year = '20160418'
select * from records where year = '20160419'
Time taken: 0.426 seconds, Fetched: 8 row(s)

上面语句内concat函数内的两个字符串是想要得到的语句,但是year是随着数据仓库中testrecords表中数据变化而变化的,所以放在函数里面,根据外面的SELECT语句从表中取出传给year,然后拼接成字符串输出。


这时你心里会不会想好了,我会写了。

但是你和高手的区别在什么地方,高手总说多思考。

所以想想还有其他方法么?


其实我觉得Hive技术中可以自己写UDF和UDAF是很自由的,比如上面这个问题其实我觉得哪怕没有concat函数也可以自己写个函数来解决,甚至我们想要实现更灵活的HQL自己写个函数完全可以实现,写完打包封装加载到Hive环境中就可以用啦。

我认为程序员是很懒的人,他会想出很多办法并实现他们减少自己的操作,同事也是服务他人的人,我们想这么多写这么多为了还是他人方便。

有问题请评论。


你可能感兴趣的:(Hadoop,SQL语句,Hive)