【问题标题】:Casting not working correctly in Amazon Athena (Presto)?投射在 Amazon Athena (Presto) 中无法正常工作?
【发布时间】:2020-03-26 16:37:38
【问题描述】:

我有一个医生执照注册数据集,其中包括每位医生的 total_submitted_charge_amount 以及医疗保险和医疗补助的权利数量。我使用了下面建议的答案中的查询:

    with datamart AS 
    (SELECT npi,
         provider_last_name,
         provider_first_name,
         provider_mid_initial,
         provider_address_1,
         provider_address_2,
         provider_city,
         provider_zipcode,
         provider_state_code,
         provider_country_code,
         provider_type,
         number_of_services,

        CASE
        WHEN REPLACE(num_entitlement_medicare_medicaid,',', '') ='' THEN
        null
        ELSE CAST(REPLACE(num_entitlement_medicare_medicaid,',', '') AS DECIMAL)
        END AS medicare_medicaid_entitlement,
        CASE
        WHEN REPLACE(total_submitted_charge_amount,',', '') ='' THEN
        null
        ELSE CAST(REPLACE(num_entitlement_medicare_medicaid,',', '') AS DECIMAL)
        END AS total_submitted_charge_amount
    FROM cmsaggregatepayment2017)
SELECT *
FROM datamart
ORDER BY  total_submitted_charge_amount DESC

不幸的是我得到了错误

INVALID_CAST_ARGUMENT:无法将 VARCHAR '' 转换为 DECIMAL(38, 0)

此查询针对aggregatepayment_data_2017 数据库运行,除非查询限定。请在我们的论坛上发布错误消息或使用查询 ID:be01d1e8-dc4d-4c75-a648-428dcb6be3a5 联系客户支持。”我尝试了十进制、实数、大整数,但没有任何方法可以转换 num_entitlement_medicare_medicaid。下面是数据的截图:

有人可以建议如何改写这个查询吗?

【问题讨论】:

  • 更好的方法是通过创建没有逗号的新输入文件来“清理”数据,或者使用CREATE TABLE AS 创建一个删除了逗号的新表(使用替换功能)。然后,您可以从新表中查询,而无需强制转换/替换任何内容。
  • @JohnRotenstein 如果我遵循您的方法,查询将如何重组
  • 您将首先 Create a Table from Query Results (CTAS) - Amazon Athena 包含 CAST(REPLACE...) 技术,如您的问题所示,但它将结果存储到新表中。然后,您可以从新表中查询而无需转换/替换,因为它已经是您想要的格式。这种方法的好处是后面的所有查询都很容易写。
  • @JohnRotenstein 你能根据你试图解释的内容改写我的查询吗?
  • double 呢?

标签: amazon-web-services amazon-s3 presto amazon-athena


【解决方案1】:

您可以使用“干净”数据将数据转换为新表,而不是在查询中进行强制转换/替换:

CREATE TABLE clean_table
WITH (format='Parquet', external_location='s3://my_bucket/clean_data/')
AS
SELECT
  npi,
  provider_last_name,
  provider_first_name,
  ...
  CASE WHEN REPLACE(num_entitlement_medicare_medicaid,',', '') ='' THEN null
       ELSE CAST(REPLACE(num_entitlement_medicare_medicaid,',', '') AS DECIMAL)
       END AS medicare_medicaid_entitlement,
  CASE WHEN REPLACE(total_submitted_charge_amount,',', '') ='' THEN null
       ELSE CAST(REPLACE(num_entitlement_medicare_medicaid,',', '') AS DECIMAL)
       END AS total_submitted_charge_amount
  FROM cmsaggregatepayment2017

您可以SELECT ... FROM clean_table 无需进行任何转换。

在数据仓库中,这种类型的过程称为 ETL(提取、转换、加载)。清理过程是将数据转换为更有用的格式的“转换”。

见:CREATE TABLE AS - Amazon Athena

【讨论】:

  • 我收到错误 GENERIC_INTERNAL_ERROR:路径不是绝对的:s3://test123data。您可能需要手动清理位置 's3://aws-athena-query-results-785609744360-us-east-1/Unsaved/2019/12/15/tables/03d3cedf-0101-43cb-91fd-cc8070db0e37 的数据' 在重试之前。 Athena 不会删除您帐户中的数据。
  • @RajPaspani 请创建一个新问题,而不是在评论中提出一个新问题。
  • stackoverflow.com/questions/59348385/…
  • 这并没有回答有关如何进行字符串转换的问题,尽管它正确地建议在作业流中更好的位置执行它。但是,如果 OP 在转换时遇到问题,那么在“选择表作为”用例中尝试使用相同的功能时,他们也会遇到相同的问题。
【解决方案2】:

您收到错误的原因是您的列中有空白值(但它不是空值),我们不能将 varchar '' 转换为十进制。您可能可以使用 case 语句。此外,根据数据集列 num_entitlement_medicare_medicaid 中的逗号“,”,您不会替换。

    SELECT npi, 
case
when REPLACE(num_entitlement_medicare_medicaid,'[^A-Za-z0-9.]', '') ='' then null
else CAST(REPLACE(num_entitlement_medicare_medicaid,'[^0-9.]', '') AS DECIMAL)
end as medicare_medicaid_entitlement,
case 
when REPLACE(total_submitted_charge_amount,'[^A-Za-z0-9.]', '') ='' then null
else CAST(REPLACE(total_submitted_charge_amount,'[^0-9.]', '') AS DECIMAL)
end as total_submitted_charge_amount
FROM cmsaggregatepayment2017

【讨论】:

  • 我尝试了您的建议,并在上面发布的问题中更新了我的查询。我仍然遇到同样的错误
  • 我假设你有像 \n 或 \t 这样的特殊字符,你不能直接看到。我正在更新查询以替换除点(。)和字母数字字符以外的特殊字符。
  • 只是建议获取特定列的记录,而无需强制转换,只需替换和列值 ='' 和实际列值。然后下载结果集并尝试在一些文本编辑器中查看数据,您也可以在其中看到特殊字符。
  • 感谢您的建议,但我已尝试运行 python 脚本,删除原始数据中使用的特殊字符,并将其上传到 s3。但是,上传完成后,Athena 根本不会读取该文件。这就是我在查询中使用强制转换的原因
【解决方案3】:

您可能想在 presto 中尝试 try_cast()。此版本适用于强制。如果有任何错误,它会避免它并移动到下一个项目。

文档:https://prestodb.io/docs/current/functions/conversion.html

【讨论】:

    猜你喜欢
    • 2013-04-22
    • 1970-01-01
    • 2023-01-26
    • 2016-10-19
    • 2014-11-15
    • 2018-09-09
    • 1970-01-01
    • 2014-08-24
    • 2017-08-26
    相关资源
    最近更新 更多