香辣鸡腿堡pro 2025-04-25 20:35 采纳率: 33.3%
浏览 4
已结题

hive命令执行遇到的问题

这段代码是我的建表,每次一到加载销售事实表数据(按年月分区)就报错,这到底是什么问题。跟着许多增大资源的帖子都试过,都没用

img


这是ods_order_details表

img


这是ods_order表

img

img


img

CREATE TABLE IF NOT EXISTS N_20243204980.ods_orders (
  order_id INT,                -- 订单ID(整数)
  customer_id STRING,          -- 客户ID(字符串)
  employee_id INT,             -- 员工ID(整数)
  order_date STRING,           -- 订单日期(改用STRING避免格式问题)
  required_date STRING,        -- 需求日期(同上)
  shipped_date STRING,         -- 发货日期(同上)
  ship_via INT,                -- 运输方式ID(整数)
  freight DECIMAL(10,2),       -- 运费(十进制,最多10位数字,其中2位小数)
  ship_name STRING,            -- 收货人姓名(字符串)
  ship_address STRING,         -- 收货地址(字符串)
  ship_city STRING,            -- 收货城市(字符串)
  ship_region STRING,          -- 收货区域(字符串)
  ship_postal_code STRING,     -- 收货邮政编码(字符串)
  ship_country STRING          -- 收货国家(字符串)
) COMMENT 'ODS层订单表'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' -- 确保数据文件实际分隔符是逗号
STORED AS TEXTFILE;
-- 创建ODS层订单明细表
CREATE TABLE IF NOT EXISTS N_20243204980.ods_order_details (
  order_id INT,                -- 订单ID(整数)
  product_id INT,              -- 产品ID(整数)
  unit_price DECIMAL(10,2),    -- 单价(十进制,最多10位数字,其中2位小数)
  quantity INT,                -- 数量(整数)
  discount DECIMAL(4,2)        -- 折扣(十进制,最多4位数字,其中2位小数)
) COMMENT 'ODS层订单明细表'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE;
-- 创建销售事实表(按年月分区)
CREATE TABLE N_20243204980.dwb_fact_sales (
    order_id INT COMMENT '订单ID',
    customer_id STRING COMMENT '客户ID',
    employee_id INT COMMENT '员工ID',
    product_id INT COMMENT '产品ID',
    shipper_id INT COMMENT '货运商ID',
    order_date STRING COMMENT '订单日期',
    unit_price DECIMAL(10,2) COMMENT '单价',
    quantity INT COMMENT '数量',
    discount DECIMAL(4,2) COMMENT '折扣',
    freight DECIMAL(10,2) COMMENT '运费',
    total_amount DECIMAL(12,2) COMMENT '总金额(计算字段: unit_price*quantity*(1-discount))',
    ship_city STRING COMMENT '收货城市(维度退化)',
    ship_country STRING COMMENT '收货国家(维度退化)'
) COMMENT 'DWB层销售事实表'
PARTITIONED BY (year_month STRING COMMENT '年月分区,格式YYYYMM')
STORED AS ORC;

-- 加载销售事实表数据(按年月分区)
INSERT OVERWRITE TABLE N_20243204980.dwb_fact_sales PARTITION(year_month)
SELECT 
    o.order_id,
    o.customer_id,
    o.employee_id,
    od.product_id,
    o.ship_via AS shipper_id,
    o.order_date,
    od.unit_price,
    od.quantity,
    od.discount,
    o.freight,
    od.unit_price * od.quantity * (1 - od.discount) AS total_amount,
    o.ship_city,
    o.ship_country,
    -- 从订单日期提取年月作为分区值
    CONCAT(YEAR(o.order_date), LPAD(MONTH(o.order_date), 2, '0')) AS year_month
FROM 
    N_20243204980.ods_orders o
JOIN 
    N_20243204980.ods_order_details od ON o.order_id = od.order_id;
  • 写回答

3条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-04-25 20:43
    关注

    让【宝码香车】来帮你解答,本回答参考DeepSeek编写,并整理提供。
    如果还有疑问可以点击头像关注私信或评论。如果答案让您满意,请采纳、点赞、关注,非常感谢!

    Hive命令执行问题分析

    根据您提供的信息,问题出现在加载销售事实表数据(按年月分区)时,报错FAILED: Execution Error return code 1 from org.apache.hadoop.hive.qlexecmrMapRedTask

    可能的原因及解决方案

    1. 日期格式问题

    您的order_date字段定义为STRING类型,但在分区计算中使用了YEAR()MONTH()函数。这些函数需要日期格式的输入。

    解决方案

    -- 修改为使用日期解析函数
    CONCAT(
        YEAR(FROM_UNIXTIME(UNIX_TIMESTAMP(o.order_date, 'yyyy/MM/dd'))), 
        LPAD(MONTH(FROM_UNIXTIME(UNIX_TIMESTAMP(o.order_date, 'yyyy/MM/dd'))), 2, '0')
    ) AS year_month
    

    2. 数据质量问题

    检查数据中是否有:

    • 空值或NULL值
    • 格式不正确的日期
    • 数值字段中的非数字字符

    解决方案

    -- 添加WHERE条件过滤无效数据
    WHERE 
        o.order_id IS NOT NULL 
        AND od.order_id IS NOT NULL
        AND o.order_date IS NOT NULL
        AND o.order_date RLIKE '^[0-9]{4}/[0-9]{2}/[0-9]{2}$'
    

    3. 分区字段问题

    确保分区字段year_month生成的值都是有效的YYYYMM格式。

    4. 资源问题

    虽然您说已尝试增大资源,但仍可尝试:

    -- 在查询前设置
    SET hive.exec.dynamic.partition=true;
    SET hive.exec.dynamic.partition.mode=nonstrict;
    SET hive.exec.max.dynamic.partitions=1000;
    SET hive.exec.max.dynamic.partitions.pernode=100;
    

    5. 完整修正方案

    -- 加载销售事实表数据(按年月分区)
    INSERT OVERWRITE TABLE N_20243204980.dwb_fact_sales PARTITION(year_month)
    SELECT 
        o.order_id,
        o.customer_id,
        o.employee_id,
        od.product_id,
        o.ship_via AS shipper_id,
        o.order_date,
        od.unit_price,
        od.quantity,
        od.discount,
        o.freight,
        od.unit_price * od.quantity * (1 - od.discount) AS total_amount,
        o.ship_city,
        o.ship_country,
        -- 修正日期处理
        CONCAT(
            YEAR(FROM_UNIXTIME(UNIX_TIMESTAMP(o.order_date, 'yyyy/MM/dd'))), 
            LPAD(MONTH(FROM_UNIXTIME(UNIX_TIMESTAMP(o.order_date, 'yyyy/MM/dd'))), 2, '0')
        ) AS year_month
    FROM 
        N_20243204980.ods_orders o
    JOIN 
        N_20243204980.ods_order_details od ON o.order_id = od.order_id
    WHERE 
        o.order_id IS NOT NULL 
        AND od.order_id IS NOT NULL
        AND o.order_date IS NOT NULL
        AND o.order_date RLIKE '^[0-9]{4}/[0-9]{2}/[0-9]{2}$';
    

    如果问题仍然存在,建议检查Hive日志获取更详细的错误信息,或尝试先处理少量数据测试。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 5月3日
  • 已采纳回答 4月25日
  • 创建了问题 4月25日