zoukankan      html  css  js  c++  java
  • hive操作语句

    设置属性:

    //设置本地执行作
    set hive.exec.mode.local.auto=true;

    //设置动态分区

    set hive.exec.dynamic.partition=true;

    set hive.exec.dynamic.partition.mode=nostrict;

    //设置reduce task数量
    set mapred.reduce.tasks=2;

    //对mapjoin优化设置
    set hive.auto.convert.join=true;

    创建表:

    //创建内部表
    create table 表名(
    字段1 类型,
    字段2 类型,
    ... ...)
    row format delimited
    fields terminated by' ';

    //创建外部表
    create external 表名(
    字段1 类型,
    字段2 类型,
    ... ...)
    row format delimited
    fields terminated by','                            
    location '/external';

    在导入数据的过程中,如果在建表的过程中没有指定location,那么就会在hive-site.xml配置的hive.metastore.warehouse.dir指定的路径下,

    以表名创建一个文件夹,之后所有有关该表的数据都会存储到此文件夹中。

    //创建分区表
    create table 表名(
    字段1 类型,
    字段2 类型,
    ... ...)
    partitioned by(分区的字段名 类型)
    row format delimited
    fields terminated by' ';

    //创建带桶的表
    //Hive使用对值进行哈希并将结果除 以桶的个数取余数。
    //要通过insert into/overwrite导入数据 ,跑了MapReduce ,hdfs才有分桶,通过load导入没有
    create table 表名(
    字段1 类型,
    字段2 类型,
    ... ...)
    clustered by(分桶的字段名) into 2 buckets
    row format delimited
    fields terminated by',';

    //创建分区分桶的表
    create table 表名(
    字段1 类型,
    字段2 类型,
    ... ...)
    partitioned by(分区的字段名 类型)
    clustered by(分桶的字段名) into 2 buckets
    row format delimited
    fields terminated by' ';

    修改表:

    //增加分区

    alter table 表名 add partition(分区字段名='新分区的值');

    注意,新建的分区是没有数据的,我们可以往里面存储数据

    //删除分区

    alter table 表名 drop if exists partiton(分区字段名='分区的值');

    //重命名表

    alter table 原表名 rename to 新表名;

    //增加一列或多列

    alter table 表名 add columns(新字段1 类型,新字段2 类型,...)

    //删除列replace   官网没有提供alter table drop的语句,该语句只对partiton去除有效

    //假设表person有字段 id,name,age,address,phone  删掉address和phone

    alter table person replace columns(id int,name String,age int);

    //替换列(修改列名)replace
    alter table t_modify replace columns(id int,name String,age2 int);

    //修改列名和类型
    alter table 表名 change 字段名 新字段名 原字段类型;
    alter table aa change time1 time String;

    修改字段类型只能从int修改为float或double,float修改为double。反过来则不行

    //清空表数据,保留表结构
    truncate table 表名;
    //拷贝表结构
    create table 表2 like 表1;
    //存储表数据
    create table 表2 as select * from 表1;
    //分组查询
    select collect_set(name),collect_set(age) from t_data group by time;
    select collect_set(name),count(*) from t_data group by time;
    注意:collect_set会去重,collect_list不会去重
    显示命令:
    //显示某数据库下的所有表

    show tables;

    //显示所有数据库

    show databases;

    //显示表的所有分区

    show partitions 表名;

    加载数据:

    //加载绝对路径数据
    load data local inpath '/home/dummy/data.log' into table t_partition partition(ds='20171113');
    //加载相对路径数据
    load data local inpath 'data.log' into table t_partition;

    //加载HDFS数据(不加local即可)
    load data inpath 'data.log' into table t_partition;

    //插入数据1
    insert into table t_partition partition(ds='20171113')
    select * from t_data where t_data.time='20171113';
    //插入数据2
    insert into table 表名 (字段a,字段b,...) values(字段值1,段值2,...);
    insert into table 表名 values(字段值1,段值2,...);

    //多插入数据
    from t_data
    insert into t_partition partition(ds='20171113')
    select * where time='20171113'
    insert into t_partition partition(ds='20171114')
    select * where time='20171114';

    //动态分区插入数据,先设置动态分区,见开头
    insert into table t_part_access_log partition(month)
    select u.valid,u.ip,u.name,u.day,u.times,u.month from
    (select valid,ip,name,
    split(time,'/')[0] day,
    split(time,'/')[1] month,
    split(time,'/')[2] times
    from t_access_log)u;

    导出数据:

    //导出表数据到本地
    insert overwrite local directory '/home/dummy/data_out.log'
    select * from t_access_log where valid!='false';
    或者
    from t_access_log
    insert overwrite local directory '/home/dummy/data_out.log'
    select * where valid!='false';
    //导出表数据到HDFS
    insert overwrite directory '/data_out.log'
    select * from t_access_log where valid!='false';

    Hive join操作:

    准备的数据源,表t_a

    1

    a

    2

    b

    3

    c

    4

    d

    准备数据源,表t_b

    1

    aa

    2

    bb

    3

    cc

    4

    dd

    5

    ee

    6

    ff

    内连接:内连接,也被称为自然连接,只有两个表相匹配的行才能在结果集中出现。返回的结果集选取了两个表中所有相匹配的数据,

    舍弃了不匹配的数据。由于内连接是从结果表中删除与其他连接表中没有匹配的所有行,所以内连接可能会造成信息的丢失

    select a.*,b.* from t_a a join t_b b on a.id=b.id;

    结果:

    1       a       1       aa

    2       b       2       bb

    3       c       3       cc

    4       d       4       dd

    外连接:外连接不仅包含符合连接条件的行,还包含左表(左连接时)、右表(右连接时)或两个边接表(全外连接)中的所有数据行。

    left outer

    select a.*,b.* from t_a a left  join t_b b on a.id=b.id;或者

    select a.*,b.* from t_a a left outer join t_b b on a.id=b.id;

    结果:

    1       a       1       aa

    2       b       2       bb

    3       c       3       cc

    4       d       4       dd

    right outer:

    select a.*,b.* from t_a a right outer join t_b b on a.id=b.id;

    结果:

    1       a       1       aa

    2       b       2       bb

    3       c       3       cc

    4       d       4       dd

    NULL    NULL    5       ee

    NULL    NULL    6       ff

    full outer:

    select a.*,b.* from t_a a full outer join t_b b on a.id=b.id;

    结果:

    1       a       1       aa

    2       b       2       bb

    3       c       3       cc

    4       d       4       dd

    NULL    NULL    5       ee

    NULL    NULL    6       ff

    left semi:

    select a.* from t_a a left semi join t_b b on a.id=b.id;

    结果:

    1       a

    2       b

    3       c

    4       d

    join 查询时,需要注意几个关键点:

    1. 等值join

    SELECT a.* FROM a JOIN b ON (a.id>b.id) 是错误的!

    但是你给出具体的值是可以的,笛卡尔积操作

    hive> select a.*,b.* from t_a a join t_b b on a.id>3;

    等效于

    select a.*,b.* from t_a a ,t_b b where a.id>3;

    结果:

    4       d       1       aa

    4       d       2       bb

    4       d       3       cc

    4       d       4       dd

    4       d       5       ee

    4       d       6       ff

    不等值查询

    select a.*,b.* from t_a a ,t_b b where a.id>b.id;

    结果:

    2       b       1       aa

    3       c       1       aa

    4       d       1       aa

    3       c       2       bb

    4       d       2       bb

    4       d       3       cc

    2. 可以 join 多于 2 个表。

    例如

    如果join中多个表的 join key 不是同一个,则 join 会被转化为2个 map/reduce 任务,

      SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2);

    如果join中多个表的 join key 是同一个,则 join 会被转化为单个 map/reduce 任务,

    SELECT a.val, b.val, c.val FROM a JOIN b  ON (a.key = b.key1) JOIN c ON (c.key = b.key1)

    3join 时,每次 map/reduce 任务的逻辑:(小表join大表)

    reducer 会缓存 join 序列中除了最后一个表的所有表的记录,再通过最后一个表将结果序列化到文件系统。

    这一实现有助于在 reduce 端减少内存的使用量。实践中,应该把最大的那个表写在最后(否则会因为缓存浪费大量内存)。

    例如:

     SELECT a.val, b.val, c.val FROM a

        JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1)

    所有表都使用同一个 join key(使用 1 次 map/reduce 任务计算)。Reduce 端会缓存 a 表和 b 表的记录,然后每次取得一个 c 表的记录就计算一次 join 结果,类似的还有:

      SELECT a.val, b.val, c.val FROM a

        JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2)

    这里用了 2 次 map/reduce 任务。第一次缓存 a 表,用 b 表序列化;第二次缓存第一次 map/reduce 任务的结果,然后用 c 表序列化。

    这里必须设置join优化

     set hive.auto.convert.join=true;

    4.LEFT,RIGHT 和 FULL OUTER 关键字用于处理 join 中空记录的情况

    例如:

      SELECT a.val, b.val FROM

    a LEFT OUTER  JOIN b ON (a.key=b.key)

    对应所有 a 表中的记录都有一条记录输出。输出的结果应该是 a.val, b.val,当 a.key=b.key 时,而当 b.key 中找不到等值的 a.key 记录时也会输出:

    a.val, NULL

    所以 a 表中的所有记录都被保留了;

    “a RIGHT OUTER JOIN b”会保留所有 b 表的记录。

     

    Join 发生在 WHERE 子句之前。如果你想限制 join 的输出,应该在 WHERE 子句中写过滤条件——或是在 join 子句中写。这里面一个容易混淆的问题是表分区的情况:

      SELECT a.val, b.val FROM a

      LEFT OUTER JOIN b ON (a.key=b.key)

      WHERE a.ds='2009-07-07' AND b.ds='2009-07-07'

    join a 表到 b 表(OUTER JOIN),列出 a.val 和 b.val 的记录。WHERE 从句中可以使用其他列作为过滤条件。但是,如前所述,如果 b 表中找不到对应 a 表的记录,b 表的所有列都会列出 NULL,包括 ds 列。也就是说,join 会过滤 b 表中不能找到匹配 a 表 join key 的所有记录。这样的话,LEFT OUTER 就使得查询结果与 WHERE 子句无关了。解决的办法是在 OUTER JOIN 时使用以下语法:

      SELECT a.val, b.val FROM a LEFT OUTER JOIN b

      ON (a.key=b.key AND

          b.ds='2009-07-07' AND

          a.ds='2009-07-07')

    这一查询的结果是预先在 join 阶段过滤过的,所以不会存在上述问题。这一逻辑也可以应用于 RIGHT 和 FULL 类型的 join 中。

    Join 是不能交换位置的。无论是 LEFT 还是 RIGHT join,都是左连接的。

      SELECT a.val1, a.val2, b.val, c.val

      FROM a

      JOIN b ON (a.key = b.key)

      LEFT OUTER JOIN c ON (a.key = c.key)

    join a 表到 b 表,丢弃掉所有 join key 中不匹配的记录,然后用这一中间结果和 c 表做 join。这一表述有一个不太明显的问题,就是当一个 key 在 a 表和 c 表都存在,但是 b 表中不存在的时候:整个记录在第一次 join,即 a JOIN b 的时候都被丢掉了(包括a.val1,a.val2和a.key),然后我们再和 c 表 join 的时候,如果 c.key 与 a.key 或 b.key 相等,就会得到这样的结果:NULL, NULL, NULL, c.val

     
  • 相关阅读:
    3月30日
    3月29日
    3月26日
    3月24
    3月22日
    3月20日
    博弈论基础
    $burnside$引理与$pacute olya$定理
    min-max容斥
    模板
  • 原文地址:https://www.cnblogs.com/dummyly/p/10059114.html
Copyright © 2011-2022 走看看