Hive Select 选择语句排除一列或多列

博客指出在某些场景下,如分区列放最后且要插入新列和数据时,排除一列或多列的SELECT语句很有用,还提及了排除特定列的示例,以及可在'hive - site.xml'中添加配置替换相关操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有时候我们需要几乎所有的列,但是不包括分区列或其中的某些列,比如分区列要放最后,我们要在之前插入新列并插入新的数据,这时候排除一列或者多列的 select 语句就十分有用了

排除num列

set hive.support.quoted.identifiers=none;
select
`(num)?+.+`
from
    (select 
    row_number() over (partition by uid order by pay_time asc) as num
    ,*
    from order) first_order
where num = 1;

排除num和uid列 

set hive.support.quoted.identifiers=none;
select
`(num|uid)?+.+`
from
    (select 
    row_number() over (partition by uid order by pay_time asc) as num
    ,*
    from order) first_order
where num = 1;

上面的 set hive.support.quoted.identifiers=none; 可以替换操作为:

在 'hive-site.xml' 中添加以下配置,

hive.support.quoted.identifiers=none

<think>我们正在解决一个Hive中的单词计数问题,类似于MapReduce中的word count。 用户之前遇到了一个语法错误,现在他想要统计Hive表中单词的出现次数。 步骤: 1. 我们需要将表中的每一行文本拆分成单词。 2. 然后对每个单词进行计数。 注意:在Hive中,我们通常使用以下方法: - 使用`split()`函数将字符串拆分成单词数组(通常按空格分割)。 - 使用`explode()`函数将数组中的每个单词变成一行。注意:`explode`是UDTF(表生成函数),需要配合`LATERAL VIEW`使用。 - 然后对单词进行分组并计数。 假设我们有一个表,名为`text_table`,其中有一个字符串类型的`line`,存储文本行。 查询步骤: a. 使用`split(line, ' ')`将每一行拆分成单词数组。 b. 使用`LATERAL VIEW explode()`将单词数组展开成多行,每行一个单词。 c. 在展开的单词表上,使用`group by`和`count(1)`进行计数。 查询语句示例: SELECT word, count(1) AS count FROM text_table LATERAL VIEW explode(split(line, ' ')) exploded_table AS word GROUP BY word ORDER BY count DESC; 但是,需要注意: - 分割符:这里使用空格,但实际可能包含标点符号其他空白字符(如逗号、句号等),可能需要更复杂的分割(例如使用正则表达式)。 - 大小写:通常我们希望忽略大小写,可以在拆分前将整个字符串转换为小写(大写)。 - 空单词:分割后可能产生空字符串,需要过滤掉。 改进的查询: SELECT word, count(1) AS count FROM text_table LATERAL VIEW explode(split(lower(line), ' ')) exploded_table AS word WHERE word != '' GROUP BY word ORDER BY count DESC; 但是,使用空格分割可能够,因为文本中可能有标点符号紧挨着单词。我们可以使用正则表达式分割,例如:`split(line, '\\W+')`,其中`\\W`表示非单词字符。但注意,这样分割会去除标点,并且将连续的非单词字符作为分隔符。 另一种方法:使用`regexp_replace`先去除标点符号,然后再拆分。例如: split(regexp_replace(line, '[^a-zA-Z0-9 ]', ''), ' ') - 这个正则表达式将非字母、数字和空格的字符替换为空字符串,然后再按空格拆分。 但是,这样可能会将连在一起的单词分开(如"hello,world"会变成"hello world"),所以也可以考虑使用正则表达式直接按非单词字符拆分: split(line, '\\W') 然而,`split`函数使用的是正则表达式,我们可以用`\\s+`表示一个多个空白字符,者`\\W+`表示一个多个非单词字符。 因此,一个更通用的拆分方式可能是: split(lower(line), '\\W+') -- 注意:这样拆分后,单词之间以非单词字符(一个多个)为分隔 但是,使用`\\W+`可能会在开头和结尾产生空字符串,所以我们需要过滤掉空字符串。 最终查询: SELECT word, count(1) AS count FROM ( SELECT split(lower(line), '\\W+') as words FROM text_table ) t LATERAL VIEW explode(words) exploded_table AS word WHERE word != '' GROUP BY word ORDER BY count DESC; 者一步到位: SELECT word, count(1) AS count FROM text_table LATERAL VIEW explode(split(lower(line), '\\W+')) exploded_table AS word WHERE word != '' GROUP BY word ORDER BY count DESC; 注意:如果表中有多列,我们只需要处理包含文本的。 如果用户有特定的表名和名,请替换`text_table`和`line`。 另外,如果文本包含了NULL值,我们需要处理,以免拆分时出错。可以加上`line IS NOT NULL`条件,者使用`nvl(line, '')`。 因此,更健壮的写法: SELECT word, count(1) AS count FROM text_table LATERAL VIEW explode(split(lower(nvl(line, '')), '\\W+')) exploded_table AS word WHERE word != '' GROUP BY word ORDER BY count DESC; 但是,如果表很大,我们可能需要考虑性能优化,例如使用MAP端聚合(Hive配置)者调整reducer的数量。 现在,我们提供一个完整的示例。 假设表名为`documents`,名为`content`,则查询为: SELECT word, count(1) AS count FROM documents LATERAL VIEW explode(split(lower(nvl(content, '')), '\\W+')) exploded_table AS word WHERE word != '' GROUP BY word ORDER BY count DESC, word; 这样,我们就得到了每个单词的出现次数,按次数降序排,次数相同的按单词字母顺序排。 注意:在Hive中,如果使用`\\W`,需要两个反斜杠,因为Hive在字符串中会进行转义。 另外,我们也可以考虑使用`trim`函数去除单词两端的空格,但这里我们使用`\\W+`分割,通常会在单词两端产生空格,因为`\\W+`已经匹配了非单词字符(包括空格),所以拆分出来的单词应该是干净的。 但是,如果用户有特殊需求,比如只统计特定长度的单词,可以在WHERE子句中添加条件,例如:`WHERE length(word) > 2`。 现在,我们根据上述思路编写查询。</think>### Hive 单词计数完整解决方案 在 Hive 中统计单词出现次数需要正确处理文本拆分和展开操作,以下是完整的解决方案: #### 1. 创建示例表 ```sql -- 创建包含文本的表 CREATE TABLE documents ( id INT, content STRING ); -- 示例数据 INSERT INTO documents VALUES (1, 'Hello world, Hive is powerful'), (2, 'Hive SQL for big data analysis'); ``` #### 2. 单词计数查询 ```sql SELECT word, COUNT(1) AS frequency FROM ( SELECT explode(split(lower(regexp_replace(content, '[^a-zA-Z ]', '')), ' ')) AS word FROM documents ) words_table WHERE word != '' -- 过滤空字符串 GROUP BY word ORDER BY frequency DESC; ``` #### 关键步骤说明: 1. **文本清洗**: - `regexp_replace(content, '[^a-zA-Z ]', '')`:移除非字母字符(保留空格)[^2] - `lower(...)`:统一转为小写(避免大小写差异) 2. **拆分单词**: - `split(..., ' ')`:按空格拆分成单词数组 3. **展开单词**: - `explode(...)`:将数组展开为多行(需嵌套在子查询中) 4. **过滤与统计**: - `WHERE word != ''`:排除空字符串 - `GROUP BY word` + `COUNT(1)`:按单词分组计数 #### 3. 查询结果示例 ``` word | frequency --------|---------- hive | 2 data | 1 world | 1 sql | 1 ... ``` #### 高级优化技巧: 1. **处理复杂分隔符**: ```sql split(content, '\\W+') -- 使用正则匹配所有非单词字符 ``` 2. **词干提取**: ```sql regexp_replace(word, 'ing$|s$', '') -- 简易词干处理 ``` 3. **停用词过滤**: ```sql WHERE word NOT IN ('the','and','is','for') ``` 4. **分区优化**: ```sql CREATE TABLE docs_partitioned ( content STRING ) PARTITIONED BY (source STRING); ``` > **性能提示**:对超大规模文本,可先过滤空值并限制处理范围: > ```sql > WHERE content IS NOT NULL AND length(content) > 0 > ``` #### 常见错误规避: 1. **`LATERAL VIEW` 误用**: - 错误:`SELECT explode(...) FROM ...` - 正确:在子查询中使用 `explode` 2. **空数组处理**: ```sql COALESCE(split(content, ' '), array()) -- 避免NULL数组 ``` 3. **特殊字符处理**: ```sql regexp_replace(content, '["()\\[\\]]', '') -- 移除引号/括号等 ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值