Hive Sql动态地从表中获取空列计数

时间:2017-06-16 09:29:41

标签: hive apache-spark-sql hiveql

我正在使用datastax + spark集成和spark SQL thrift服务器,它为我提供了一个Hive SQL接口来查询Cassandra中的表。

我的数据库中的表是动态创建的,我想要做的是根据表名在表的每一列中获取空值的计数。

我可以使用describe database.table获取列名,但在hive SQL中,如何在另一个为所有列计数null的select查询中使用其输出。

更新1:使用Dudu解决方案回溯

  

运行查询时出错:TExecuteStatementResp(status = TStatus(errorCode = 0,   errorMessage =“org.apache.spark.sql.AnalysisException:无效的使用情况   爆炸中的'*'/ json_tuple / UDTF;“,sqlState = None,   infoMessages = [“ org.apache.hive.service.cli.HiveSQLException:org.apache.spark.sql.AnalysisException:   explode / json_tuple / UDTF中的''用法无效;:16:15“,   'org.apache.spark.sql.hive.thriftserver.SparkExecuteStatementOperation:组织$阿帕奇$火花$ SQL $蜂巢$ thriftserver $ SparkExecuteStatementOperation $$执行:SparkExecuteStatementOperation.scala:258',   'org.apache.spark.sql.hive.thriftserver.SparkExecuteStatementOperation:runInternal:SparkExecuteStatementOperation.scala:152',   'org.apache.hive.service.cli.operation.Operation:运行:Operation.java:257',   'org.apache.hive.service.cli.session.HiveSessionImpl:executeStatementInternal:HiveSessionImpl.java:388',   'org.apache.hive.service.cli.session.HiveSessionImpl:executeStatement:HiveSessionImpl.java:369',   'org.apache.hive.service.cli.CLIService:executeStatement:CLIService.java:262',   'org.apache.hive.service.cli.thrift.ThriftCLIService:ExecuteStatement:ThriftCLIService.java:437',   'org.apache.hive.service.cli.thrift.TCLIService $处理器$ ExecuteStatement:的getResult:TCLIService.java:1313',   'org.apache.hive.service.cli.thrift.TCLIService $处理器$ ExecuteStatement:的getResult:TCLIService.java:1298',   'org.apache.thrift.ProcessFunction:过程:ProcessFunction.java:39',   'org.apache.thrift.TBaseProcessor:过程:TBaseProcessor.java:39',   'org.apache.hive.service.auth.TSetIpAddressProcessor:过程:TSetIpAddressProcessor.java:56',   'org.apache.thrift.server.TThreadPoolServer $ WorkerProcess:运行:TThreadPoolServer.java:286',   'java.util.concurrent.ThreadPoolExecutor中:runWorker:ThreadPoolExecutor.java:1142',   'java.util.concurrent.ThreadPoolExecutor中的$工人:运行:ThreadPoolExecutor.java:617',   'java.lang.Thread:run:Thread.java:745'],statusCode = 3),   operationHandle =无)

3 个答案:

答案 0 :(得分:4)

在以下解决方案中,无需单独处理每个列。 结果是列索引和该列中的空值数 您可以稍后通过列索引将其连接到从Metastore检索到的信息 一个限制是包含确切文本null的字符串将被视为空值。

演示

CTE(由mytable定义的with mytable as)显然可以替换为实际表格

with        mytable as 
            (
                select  stack
                        (
                            5

                           ,1   ,1.2     ,date '2017-06-21'     ,null
                           ,2   ,2.3     ,null                  ,null
                           ,3   ,null    ,null                  ,'hello'
                           ,4   ,4.5     ,null                  ,'world'
                           ,5   ,null    ,date '2017-07-22'     ,null
                        ) as (id,amt,dt,txt)
            )

select      pe.pos                                          as col_index
           ,count(case when pe.val='null' then 1 end)       as nulls_count

from        mytable t lateral view posexplode (split(printf(concat('%s',repeat('\u0001%s',field(unhex(1),t.*,unhex(1))-2)),t.*),'\\x01')) pe

group by    pe.pos       
;
+-----------+-------------+
| col_index | nulls_count |
+-----------+-------------+
|         0 |           0 |
|         1 |           2 |
|         2 |           3 |
|         3 |           3 |
+-----------+-------------+

答案 1 :(得分:3)

您可以使用

代替描述database.table

Select column_name from system_schema.columns where keyspace_name='YOUR KEYSPACE' and table_name='YOUR TABLE'

上表中还有一个名为kind的列,其值为partition_key,clustering,regular

值为partition_keyclustering的列不会包含空值。

对于其他列,您可以使用

select sum(CASE WHEN col1 is NULL THEN 1 ELSE 0 END) as col1_cnt,sum(CASE WHEN col2 is NULL THEN 1 ELSE 0 END) as col2_cnt from table1 where col1 is null;

你也可以尝试以下查询(我自己没试过)

SELECT COUNT(*)-COUNT(col1) As A, COUNT(*)-COUNT(col2) As B, COUNT(*)-COUNT(col3) As C
FROM YourTable; 

可能对于上述查询,您可以每次都为count而不是count(*)创建变量。

注意: system_schema.columns是cassandra表,cassandra用户应具有此表的读取权限

答案 2 :(得分:-4)

您必须分别计算每列的空值。例如 -

select count(*) from mytable where col1 is null;
select count(*) from mytable where col2 is null;