回知识库

AWS CUR 学习文档

面向具备 Cloud 与 SQL 基础的读者,四步读懂 AWS 成本与使用量报告。

CUR 是什么

AWS 最细粒度的账单数据集:把每笔费用按「产品 × 使用类型 × 操作 × 时间」拆成明细行,可细到小时级 + 单个资源

Cost Explorer vs CUR

📊

Cost Explorer

「看板」
  • 预设维度,图表现成
  • 快速查看趋势
  • 灵活度有限
🗄️

CUR

「数据仓库」
  • 上百字段,任意 SQL 查询
  • 小时级 + 资源 ID 粒度
  • 精细分摊 / 审计 / 自定义看板

数据是怎么流动的

🧾
账单事件
⚙️
AWS 生成 CUR
每天刷新
🪣
投递到 S3
Parquet
🗂️
Glue 建表
🔍
Athena SQL
📈
看板/报表

两个版本

CUR(经典版)

在 Billing 控制台创建
lineItem/UnblendedCost

CUR 2.0(Data Exports)推荐

结构更统一,支持列筛选
line_item_unblended_cost
创建建议 勾选 Include resource IDs + Refresh automatically,格式选 Parquet,粒度选 Hourly,并开启与 Athena 集成。

如何配置权限

配置 CUR 涉及三层权限,看懂这张图就理清了全局。

👤
① 谁能创建报告
IAM 权限 cur:* / bcm-data-exports:*
🪣
② S3 桶允许 AWS 写入
Bucket Policy
🔍
③ 谁能查询数据
Athena + Glue + S3 读
在哪个账户创建? 用 Organizations 时,在管理账户(Payer Account)创建,报告即包含全部成员账户费用,便于统一分摊。

① 创建报告的 IAM 权限

"Action": [
  "cur:PutReportDefinition",
  "cur:DescribeReportDefinitions",
  "cur:ModifyReportDefinition",
  "cur:DeleteReportDefinition",
  // CUR 2.0 额外需要
  "bcm-data-exports:CreateExport",
  "bcm-data-exports:GetExport",
  // 建桶还需 s3:CreateBucket / PutBucketPolicy
]

② S3 桶策略(最容易配错)

CUR 由账单服务把文件写进你的桶,Principal 必须是 billingreports.amazonaws.com

"Principal": { "Service": "billingreports.amazonaws.com" },
"Action": [
  "s3:GetBucketAcl", "s3:GetBucketPolicy",  // 读桶属性
  "s3:PutObject"                        // 写入报告文件
],
"Resource": "arn:aws:s3:::your-cur-bucket(/*)"
三个常见坑 ① Principal 写错;② 桶名和报告配置不一致;③ 桶开了 SSE-KMS 却没给账单服务 KMS 权限 → 写入失败、S3 里一直没数据。

创建报告的步骤

1
管理账户 → Billing → Data Exports
2
命名报告,勾选包含资源 ID
3
选 S3 桶 + Parquet + Hourly
4
开启 Athena 集成
5
等数小时~24h 出首批数据

③ 查询者需要的权限

athena:* 查询 glue:GetTable / GetDatabase 读表结构 s3:GetObject(CUR 桶) s3:PutObject(Athena 结果桶)

核心字段含义

字段有上百个,但不用背。先看懂「一行数据」,剩下的都是它的扩展。

一行 CUR 是什么? 一行 = 某个小时 × 某个资源 × 某一个计量项的费用。同一台 EC2 在同一小时,可能产生「实例小时」「EBS 容量」「流量」多行。

先解剖一行真实数据

示例:东京区一台 m5.large Linux 实例,2026-07-15 08:00 这一小时的按需费用
① 什么时候— 时间维度,决定你能做小时级分析
line_item_usage_start_date
2026-07-15 08:00:00
用量开始时间。按天/月汇总就靠它
bill_billing_period_start_date
2026-07-01
账期。通常也是分区列,加进 WHERE 能省钱
② 谁付钱 / 谁用的— 多账户组织的分摊基础
bill_payer_account_id
111111111111
付款账户(管理账户),全表基本同一个值
line_item_usage_account_id
222222222222
真正产生费用的成员账户 — 按账户拆账用这个
③ 用了什么— 服务 / 计量项 / 操作 / 规格
line_item_product_code
AmazonEC2
服务代码(机器可读、稳定)。写 WHERE 条件优先用它
product_product_name
Amazon Elastic Compute Cloud
服务显示名(人类可读,可能变动)
line_item_usage_type
APN1-BoxUsage:m5.large
计量项,最有信息量的字段(第 4 页专门拆解)
line_item_operation
RunInstances
执行的操作,用来区分 Linux / Windows 等
line_item_line_item_description
$0.124 per On Demand Linux m5.large Instance Hour
计费说明,自带单价。排查「为什么这么贵」最直观
product_region
ap-northeast-1
区域
product_instance_type
m5.large
实例规格,做 rightsizing 分析用
④ 用了多少— 用量必须配单位才有意义
line_item_usage_amount
1.0
用量数值
pricing_unit
Hrs
单位:Hrs / GB-Mo / Requests…
不同 usage_type 单位不同,不要跨类型求和
⑤ 花了多少— 三种口径,见下方对比
line_item_unblended_cost
0.124
实际发生的钱,等于账单口径。90% 的查询用它
pricing_public_on_demand_cost
0.124
同样用量按官网按需价要多少钱 → 算折扣/节省额的分母
⑥ 这笔钱归谁— 成本归因的关键
line_item_resource_id
i-0a1b2c3d4e5f
资源 ID。创建报告时必须勾 Include resource IDs,否则这列是空
resource_tags_user_team
payment
你自己的标签 Team=payment。标签需在账单控制台激活为成本分摊标签后才会出现
⑦ 这行什么性质— 决定能不能直接 SUM
line_item_line_item_type
Usage
行类型:用量 / 税 / 抵扣 / RI 覆盖…(下方专门讲)
记住这条主线 时间 + 账户 + 计量项 + 用量×单位 + 费用 + 标签 + 行类型。 任何 CUR 查询,本质都是「选几个维度 GROUP BY,把费用 SUM 起来」。
下一页 → 认识字段前缀,遇到没见过的字段也能猜出它属于哪一类。

字段家族:按前缀归类

本文全部采用 CUR 2.0(Data Exports)命名:全小写 snake_case,表名 COST_AND_USAGE_REPORT。 遇到不认识的字段,先看前缀就知道它回答什么问题。

CUR 2.0 的两个结构特点固定 schema:共 125 列,不会像经典 CUR 那样因为你新增了标签或服务而每月变列。
嵌套数据:把稀疏的列收成 key-value 形式的映射列(如 resource_tags),也可以在导出时选择把嵌套 key 摊平成独立列。 官方把字段分成 13 组,见 AWS 官方 CUR 2.0 表字典
这行唯一吗?
identity_
identity_line_item_id
identity_time_interval
属于哪张账单?
bill_
bill_payer_account_id
bill_payer_account_name (2.0 新增)
bill_billing_period_start_date
bill_invoice_id · bill_bill_type
用了什么、花了多少?最核心
line_item_
line_item_product_code · line_item_usage_type · line_item_operation · line_item_line_item_description · line_item_usage_amount · line_item_unblended_cost · line_item_line_item_type · line_item_resource_id · line_item_usage_account_id
line_item_usage_account_name (2.0 新增)
这资源长什么样?
product_
product_instance_type · product_region_code · product_servicecode · product_product_family · product_location
其余上百个属性收在 product 映射列里
按什么价格算的?
pricing_
pricing_public_on_demand_cost · pricing_public_on_demand_rate · pricing_unit · pricing_term · pricing_purchase_option
RI 覆盖情况?
reservation_
reservation_effective_cost · reservation_reservation_arn · reservation_unused_quantity · reservation_upfront_value
SP 覆盖情况?
savings_plan_
savings_plan_savings_plan_effective_cost · savings_plan_savings_plan_arn · savings_plan_savings_plan_rate
注意前缀重复了一次
该记到谁头上?
resource_tags映射列
你自己打的标签,需在账单控制台激活为成本分摊标签后才有值
业务口径怎么归?
cost_category映射列
Cost Categories 里定义的业务分组(如 BU / 环境 / 产品线)
拿到了什么折扣?
discount映射列
自动化折扣明细,另有汇总列 total_discount
容器级怎么拆?
split_line_item_需开配置
把一台 EC2 的费用按 ECS / EKS 任务再拆一层,需开启 INCLUDE_SPLIT_COST_ALLOCATION_DATA
容量预留用了吗?
capacity_reservation_2.0 新增
capacity_reservation_capacity_reservation_arn / _status / _type,需开启 INCLUDE_CAPACITY_RESERVATION_DATA

映射列(map)怎么查

这是 CUR 2.0 和经典 CUR 最大的写法差异。取值方式取决于你创建导出时有没有把嵌套 key 摊平成独立列

映射列保持嵌套时这样写摊平成独立列时这样写说明
resource_tags resource_tags['user_team'] resource_tags_user_team 标签 Team。本文 SQL 用例采用摊平写法
cost_category cost_category['bu'] cost_category_bu Cost Categories 定义的分组
product product['vcpu'] product_vcpu 常用属性已是独立列,冷门属性才需要从 map 取
discount discount['bundled_discount'] discount_bundled_discount 折扣明细
上手第一件事 列名细节(有没有摊平、前缀是否重复、ARN 拼作 arn 还是别的形式)会随导出配置不同, 先跑一句 SHOW COLUMNS FROM curSELECT * FROM cur LIMIT 1 对一遍,比照文档更可靠。
前缀只解决「字段属于哪一类」。真正决定数字对不对的,是下一页的行类型

行类型 line_item_line_item_type:最容易算错的字段

同一张表里混着「真实用量」「税」「抵扣」「预付承诺」等不同性质的行。不区分类型直接 SUM,结果一定是错的。

类型金额正负它代表什么该看哪个费用字段
Usage按需用量,最主要的一类行unblended_cost
Tax税费(如日本消费税)unblended_cost
Fee一次性/固定费用,如 RI 全额预付、Support 费unblended_cost
CreditAWS 给的抵扣券、活动信用unblended_cost
Refund退款unblended_cost
RIFeeRI 的月度承诺费(不是用量!按月摊到每小时记账)unblended_cost
DiscountedUsage通常 0RI 覆盖的用量。钱已在 RIFee 里付过,所以这行 unblended 是 0reservation_effective_cost
SavingsPlanCoveredUsage通常 0SP 覆盖的用量,同理savings_plan_savings_plan_effective_cost
SavingsPlanRecurringFeeSP 的小时承诺费unblended_cost
SavingsPlanNegation抵消 SP 覆盖行的记账项,避免重复计费unblended_cost
BundledDiscount
EdpDiscount
PrivateRateDiscount
各类协议折扣(EDP/PPA 等)unblended_cost
算总账的三种正确姿势看账单口径(发票金额)SUM(unblended_cost) 全类型都要,别过滤。
看纯用量结构(做优化分析):只留 line_item_line_item_type='Usage',避免抵扣行干扰排名。
看真实单位成本(摊销口径):Usage 用 unblended,RI/SP 覆盖行改用 effective_cost,并排除 RIFee / SavingsPlanRecurringFee,否则重复计费。

拆解 usage_type:一个字符串包含三层信息

APN1
区域代码
-
BoxUsage
计量项目
:
m5.large
规格 / 细分
东京区 · EC2 实例小时 · m5.large  →  不带区域前缀时,默认是弗吉尼亚 us-east-1
USE1 弗吉尼亚 USW2 俄勒冈 APN1 东京 APN2 首尔 APS1 新加坡 APS3 孟买 EUW1 爱尔兰 EUC1 法兰克福

line_item_product_code:服务的机器可读标识

product_product_name 是给人看的显示名(会变、有空格), line_item_product_code稳定的服务代码,写 WHERE 条件优先用它。

line_item_product_codeproduct_product_name这个 code 底下都装了什么
AmazonEC2Amazon Elastic Compute Cloud不只是实例:EC2 实例 + EBS 卷 + 快照 + NAT Gateway + 弹性 IP + 区域内/跨 AZ 流量
AmazonS3Amazon Simple Storage Service存储容量 + 请求次数 + 取回 + 生命周期转换
AmazonRDSAmazon Relational Database Service数据库实例 + 存储 + IOPS + 备份 + 快照导出
AWSELBElastic Load BalancingALB / NLB / CLB 的小时费 + LCU
AWSLambdaAWS Lambda请求数 + GB-Second + 预置并发
AmazonCloudFrontAmazon CloudFront出站流量 + 请求数(按边缘位置分区域)
AWSDataTransferAWS Data Transfer跨区域流量,和 EC2 内部的区域内流量分开记
AmazonElastiCacheAmazon ElastiCache缓存节点小时费 + 备份
awskmsAWS Key Management Service注意:部分 code 是全小写的,写死字符串前先 SELECT DISTINCT 确认
AWSSupportBusinessAWS Support (Business)Support 费,通常 line_item_line_item_type = Fee,无 resource_id
最常见的误判 「EC2 这个月花了 $12,400」——这个数字里可能有 30% 根本不是实例,而是 EBS 卷、快照、NAT Gateway 和跨 AZ 流量。 只看 product_code 会误判优化方向,必须再往下拆 usage_type

五个字段配合,才能定位到「哪个服务的哪笔钱」

下面每张卡片就是 CUR 里一行的真实字段组合:product_code 定服务、 usage_type 定计量项、operation 定细分、 description 给单价、resource_id 落到具体资源。

🖥️EC2 实例(Linux)AmazonEC2
usage_typeAPN1-BoxUsage:m5.large
operationRunInstances
description$0.124 per On Demand Linux m5.large Instance Hour
resource_idi-0a1b2c3d4e5f67890
裸实例 ID · 单位 Hrs
🪟EC2 实例(Windows)AmazonEC2
usage_typeAPN1-BoxUsage:m5.large
operationRunInstances:0002
description$0.268 per On Demand Windows m5.large Instance Hour
resource_idi-0f9e8d7c6b5a43210
usage_type 与 Linux 完全一样,只能靠 operation 后缀区分 OS
💾EBS 卷AmazonEC2
usage_typeAPN1-EBS:VolumeUsage.gp3
operationCreateVolume-Gp3
description$0.096 per GB-month of General Purpose (gp3) provisioned storage - Asia Pacific (Tokyo)
resource_idvol-0c1d2e3f4a5b6c7d8
product_code 仍是 AmazonEC2,但单位是 GB-Mo 不是 Hrs
🌐NAT GatewayAmazonEC2
usage_typeAPN1-NatGateway-Hours
operationNatGateway
description$0.062 per NAT Gateway Hour
resource_idarn:aws:ec2:ap-northeast-1:2222…:natgateway/nat-0abc123
这里 resource_id 是完整 ARN,和实例的裸 ID 形态不同
🔀跨 AZ 流量AmazonEC2
usage_typeAPN1-APN1-AZ-DataTransfer-Out
operationRunInstances
description$0.01 per GB - regional data transfer between Availability Zones
resource_idi-0a1b2c3d4e5f67890
流量挂在发出方实例上;usage_type 里区域码出现两次 = 同区跨 AZ
🪣S3 存储容量AmazonS3
usage_typeAPN1-TimedStorage-ByteHrs
operationStandardStorage
description$0.025 per GB - first 50 TB / month of storage used
resource_idmy-app-logs-bucket
S3 的 resource_id 是桶名,不是 ARN;operation 区分存储类别
📨S3 请求数AmazonS3
usage_typeAPN1-Requests-Tier1
operationPutObject
description$0.0047 per 1,000 PUT/COPY/POST/LIST requests
resource_idmy-app-logs-bucket
同一个桶会同时产生存储行和请求行 → 一个资源多行
🗃️RDS 实例AmazonRDS
usage_typeAPN1-InstanceUsage:db.r6g.large
operationCreateDBInstance:0002
description$0.30 per RDS db.r6g.large Multi-AZ instance hour running MySQL
resource_idarn:aws:rds:ap-northeast-1:2222…:db:prod-mysql-01
operation 的数字后缀在 RDS 里表示数据库引擎(MySQL / PG / Aurora…)
Lambda 计算AWSLambda
usage_typeAPN1-Lambda-GB-Second
operationInvoke
description$0.0000166667 for GB-Second - Asia Pacific (Tokyo)
resource_idarn:aws:lambda:ap-northeast-1:2222…:function:order-handler
另有一行 Lambda-Request 记请求数,两行合起来才是总成本
⚖️ALB 负载均衡AWSELB
usage_typeAPN1-LoadBalancerUsage
operationLoadBalancing:Application
description$0.0243 per Application LoadBalancer-hour (or partial hour)
resource_idarn:aws:elasticloadbalancing:…:loadbalancer/app/prod-alb/50dc6c49
operation 区分 ALB / NLB / CLB;另有 LCUUsage 行记容量单位
description 怎么用 它是唯一自带单价的人类可读字段,排查「这项为什么这么贵」最快 —— 一眼看到 $0.268/h 就知道是 Windows License。 但它是自由文本、会随定价调整变化,不要拿它做 GROUP BY 的稳定键,稳定键用 product_code + usage_type + operation 三件套。

resource_id 的形态因服务而异

资源类型形态示例
EC2 实例裸 IDi-0a1b2c3d4e5f67890
EBS 卷 / 快照裸 IDvol-0c1d2e3f4a5b6c7d8 · snap-0e2f3a4b5c6d7e8f9
S3 桶名称my-app-logs-bucket
RDS / Lambda / ALB / NAT / DynamoDB完整 ARNarn:aws:rds:ap-northeast-1:222222222222:db:prod-mysql-01
Tax / Fee / Support / Credit 等非资源行''(空字符串,不是 NULL)
两个实操坑形态不统一:想和 CMDB / 资源清单 join,得先规范化,例如 element_at(split(line_item_resource_id,'/'),-1)split_part(line_item_resource_id,':',-1) 取最后一段。
空值判断:非资源行是空字符串而非 NULL,过滤要用 line_item_resource_id <> '',只写 IS NOT NULL 会漏。

费用字段:三种口径,别混用

Unblended 未混合
line_item_unblended_cost
当刻实际发生的钱,加总 = 发票金额。
默认就用它。
Blended 混合
line_item_blended_cost
组织内按平均费率摊算。
一般不用,除了内部「公平」记账。
Amortized 摊销
reservation_effective_cost
savings_plan_..._effective_cost
把 RI/SP 预付费摊回到每小时用量,看真实单位成本。
用一个具体例子看懂差别
同一台 m5.large(按需 $0.124/h),分别在「按需」和「被 RI 覆盖」两种情况下,CUR 里长得完全不同:
场景line_item_line_item_typeunblendedeffective_costpublic_on_demand
纯按需跑 1 小时 Usage $0.124 $0.124
被 RI 覆盖的这 1 小时 DiscountedUsage $0.00 $0.062 $0.124
该 RI 的月度承诺费 RIFee $45.26
关键结论 只看 unblended,会以为这台被 RI 覆盖的机器「不花钱」(0 元),钱其实躲在 RIFee 行里。 想回答「这台机器每小时真实成本多少」,必须用 摊销口径 effective_cost

本页速记

① 维度看这 5 个
usage_account_id · product_code · usage_type · operation · resource_id
② 金额看这 3 个
unblended_cost(账单) · effective_cost(摊销) · public_on_demand_cost(原价)
③ 永远先看行类型
line_item_line_item_type 决定这行该怎么算,忘了它 = 数字错

30 个 SQL 查询用例

全部只用下面这 19 个字段组合而成,按分析目的分成 7 组。表名统一写 cur,请替换成你的实际表名。

可用字段清单(这就是你的调色板)

角色字段在查询里负责什么
时间 line_item_usage_start_date 唯一的时间轴。DATE() 出天、date_trunc('hour',…) 出小时
账户 payer
account_id · account_name
line_item_usage_account_id
付款账户 + 用量账户。account_id / account_name 通常是视图为 line_item_usage_account_id 加的友好别名,用哪个都行
行性质 line_item_line_item_type 几乎每条查询都要用。算发票不过滤,做分析只留 'Usage'
服务与
计量项
service
line_item_product_code
line_item_usage_type
line_item_operation
line_item_line_item_description
从粗到细的四级下钻:服务名 → 服务代码 → 计量项 → 操作,description 补上单价文案
标签 resource_tags_user_project
resource_tags_user_service_name
resource_tags_user_name
业务归属三件套:项目 / 业务服务 / 资源名。对应标签 Projectservice_nameName
资源 line_item_resource_id 最细粒度。非资源行是空字符串,过滤用 <> ''
数量与
金额
line_item_usage_amount
line_item_unblended_cost
line_item_net_unblended_cost
pricing_public_on_demand_cost
用量 · 实付 · 折后净额 · 按需原价。
三个金额两两相减就能算出折扣、有效单价
三个金额字段的关系,先记住这条链 pricing_public_on_demand_cost(官网原价) ≥ line_item_unblended_cost(账单实付) ≥ line_item_net_unblended_cost(扣掉 EDP/PPA 等协议折扣后的净额)。 没有折扣协议时后两者相等;对内汇报口径先跟财务确认用哪个
两个通用提速习惯先卡时间范围line_item_usage_start_date 一定要给上下界,别全表扫。
用上分区列:CUR 表通常按账期分区(列名可能叫 billing_periodbill_billing_period_start_date),WHERE 里带上它,扫描量和费用都会大幅下降。

第 1 组 · 对账与总量(1–5)

目标:先让总数和账单对上,再往下拆。顺序不能颠倒 —— 总数不对,后面的排名全是错的。

1

当月总花费(发票口径)

对账第一步
-- 关键:不要过滤 line_item_line_item_type,税/抵扣/退款都算进来才等于账单
SELECT ROUND(SUM(line_item_unblended_cost),2)     AS unblended,
       ROUND(SUM(line_item_net_unblended_cost),2) AS net_unblended
FROM cur
WHERE line_item_usage_start_date >= DATE '2026-07-01'
  AND line_item_usage_start_date <  DATE '2026-08-01';
2

三种金额口径一次看清 + 整体折扣率

知道自己省了多少
SELECT ROUND(SUM(pricing_public_on_demand_cost),2) AS list_price,
       ROUND(SUM(line_item_unblended_cost),2)      AS paid,
       ROUND(SUM(line_item_net_unblended_cost),2)  AS net_paid,
       ROUND(100 * (1 - SUM(line_item_net_unblended_cost)
                        / NULLIF(SUM(pricing_public_on_demand_cost),0)),1) AS discount_pct
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_start_date >= DATE '2026-07-01';
为什么限定 Usage pricing_public_on_demand_cost 只在用量行上有值,混入税费和抵扣行会把折扣率算歪。
3

行类型构成:钱都是什么性质

看懂表里混了什么
SELECT line_item_line_item_type AS line_type,
       COUNT(*)                                   AS row_cnt,
       ROUND(SUM(line_item_unblended_cost),2)     AS unblended,
       ROUND(SUM(line_item_net_unblended_cost),2) AS net
FROM cur
WHERE line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1
ORDER BY unblended DESC;
每个月先跑一次这条 它会告诉你这个账期有没有出现新的行类型(比如第一次买了 SP、第一次拿到 Credit),避免后续查询漏算。
4

服务花费排行(纯用量口径)

找花钱大户
SELECT service,
       line_item_product_code AS product_code,
       ROUND(SUM(line_item_unblended_cost),2)     AS unblended,
       ROUND(SUM(line_item_net_unblended_cost),2) AS net
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1,2
ORDER BY net DESC
LIMIT 20;
EC2
$12,400
RDS
$7,700
S3
$4,750
DataTransfer
$3,200
Lambda
$1,350
用例 4 的输出画成图大概是这样(示意数据)
5

各账户花费排行

跨账户拆账
SELECT payer,
       line_item_usage_account_id AS account_id,
       account_name,
       ROUND(SUM(line_item_unblended_cost),2)     AS unblended,
       ROUND(SUM(line_item_net_unblended_cost),2) AS net
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1,2,3
ORDER BY net DESC;
payer 和 account_id 的区别 payer 是付款账户,整张表基本同一个值; line_item_usage_account_id 才是真正产生费用的成员账户。拆账永远用后者。 如果你的表已有 account_id 友好列,直接用它,效果一样。
总数对上了 → 下一组开始看时间维度,抓涨幅和异常。

第 2 组 · 趋势与异常(6–10)

目标:回答「什么时候涨的、涨在哪」。所有查询都围绕 line_item_usage_start_date 展开。

6

每日费用趋势

最常用的一张折线图
SELECT DATE(line_item_usage_start_date) AS usage_day,
       ROUND(SUM(line_item_unblended_cost),2) AS daily_cost
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1
ORDER BY usage_day;
7

按小时看,抓住尖峰时段

CUR 独有的小时级能力
SELECT date_trunc('hour', line_item_usage_start_date) AS usage_hour,
       ROUND(SUM(line_item_unblended_cost),4) AS hourly_cost
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_product_code = 'AmazonEC2'
  AND line_item_usage_start_date >= DATE '2026-07-20'
  AND line_item_usage_start_date <  DATE '2026-07-27'
GROUP BY 1
ORDER BY usage_hour;
能看出什么 夜间不降的曲线 = 有该关没关的资源;整齐的方波 = 定时任务;毛刺 = 弹性扩容。 这是 Cost Explorer 做不到的粒度。
8

日环比突增 Top 20(窗口函数)

自动找异常,不用肉眼看图
WITH daily AS (
  SELECT DATE(line_item_usage_start_date) AS usage_day,
         service,
         SUM(line_item_unblended_cost) AS cost
  FROM cur
  WHERE line_item_line_item_type = 'Usage'
    AND line_item_usage_start_date >= DATE '2026-07-01'
  GROUP BY 1,2
)
SELECT usage_day, service,
       ROUND(cost,2)                                    AS cost,
       ROUND(LAG(cost) OVER (PARTITION BY service ORDER BY usage_day),2) AS prev_day,
       ROUND(cost - LAG(cost) OVER (PARTITION BY service ORDER BY usage_day),2) AS delta
FROM daily
ORDER BY delta DESC
LIMIT 20;
9

月环比:本月 vs 上月,按服务

月度复盘固定动作
SELECT service,
       ROUND(SUM(CASE WHEN line_item_usage_start_date >= DATE '2026-07-01'
                      THEN line_item_unblended_cost ELSE 0 END),2) AS this_month,
       ROUND(SUM(CASE WHEN line_item_usage_start_date <  DATE '2026-07-01'
                      THEN line_item_unblended_cost ELSE 0 END),2) AS last_month,
       ROUND(SUM(CASE WHEN line_item_usage_start_date >= DATE '2026-07-01'
                      THEN line_item_unblended_cost ELSE -line_item_unblended_cost END),2) AS diff
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_start_date >= DATE '2026-06-01'
  AND line_item_usage_start_date <  DATE '2026-08-01'
GROUP BY 1
ORDER BY diff DESC;
比较月份要对齐天数 7 月 31 天、6 月 30 天,直接比总额会天然多 3%。要么改成比日均,要么只比同样的前 N 天。
10

锁定某一天,下钻到计量项

异常定位的收口动作
-- 从用例 8 找到「7 月 23 日某服务暴涨」,用这条查出具体是什么在涨
SELECT account_name, service,
       line_item_usage_type, line_item_operation,
       ROUND(SUM(line_item_usage_amount),2)   AS qty,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_start_date >= DATE '2026-07-23'
  AND line_item_usage_start_date <  DATE '2026-07-24'
GROUP BY 1,2,3,4
ORDER BY cost DESC
LIMIT 30;
知道什么时候涨了 → 下一组定位到是哪个账户。

第 3 组 · 账户与组织(11–14)

目标:在多账户组织里把钱分清楚。主角是 payer / account_id / account_name

11

各账户占比(窗口函数算百分比)

一眼看出集中度
SELECT account_id, account_name,
       ROUND(SUM(line_item_unblended_cost),2) AS cost,
       ROUND(100.0 * SUM(line_item_unblended_cost)
             / SUM(SUM(line_item_unblended_cost)) OVER (),1) AS pct
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1,2
ORDER BY cost DESC;
技巧 SUM(SUM(x)) OVER () 是聚合套窗口,一次查询就能同时拿到明细和全局合计,不用子查询。
12

每个账户的 Top 3 服务

快速画出组织全貌
WITH t AS (
  SELECT account_name, service,
         SUM(line_item_unblended_cost) AS cost,
         ROW_NUMBER() OVER (PARTITION BY account_name
                            ORDER BY SUM(line_item_unblended_cost) DESC) AS rn
  FROM cur
  WHERE line_item_line_item_type = 'Usage'
    AND line_item_usage_start_date >= DATE '2026-07-01'
  GROUP BY 1,2
)
SELECT account_name, service, ROUND(cost,2) AS cost
FROM t
WHERE rn <= 3
ORDER BY account_name, cost DESC;
13

本月新出现的「账户 × 服务」组合

发现没人报备的新用量
WITH this_m AS (
  SELECT account_name, service, SUM(line_item_unblended_cost) AS cost
  FROM cur
  WHERE line_item_line_item_type = 'Usage'
    AND line_item_usage_start_date >= DATE '2026-07-01'
  GROUP BY 1,2
), last_m AS (
  SELECT DISTINCT account_name, service
  FROM cur
  WHERE line_item_line_item_type = 'Usage'
    AND line_item_usage_start_date >= DATE '2026-06-01'
    AND line_item_usage_start_date <  DATE '2026-07-01'
)
SELECT t.account_name, t.service, ROUND(t.cost,2) AS new_cost
FROM this_m t
LEFT JOIN last_m l
  ON t.account_name = l.account_name AND t.service = l.service
WHERE l.service IS NULL
ORDER BY new_cost DESC;
治理价值 新服务第一次出现往往是试用、PoC 或误操作。每月跑一次,能在费用还很小的时候就发现。
14

钻进单个账户看内部构成

找到账户 owner 谈优化
SELECT service, line_item_usage_type,
       ROUND(SUM(line_item_usage_amount),2)   AS qty,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_account_id = '222222222222'
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1,2
ORDER BY cost DESC
LIMIT 30;
定位到账户 → 下一组把服务内部拆开,看具体花在什么计量项上。

第 4 组 · 服务与计量项下钻(15–19)

目标:把「EC2 花了 1.2 万」拆成可以动手优化的条目。主角是 product_code + usage_type + operation + description

15

三级下钻:服务 → 计量项 → 操作

本组最常用的一条
SELECT line_item_product_code AS product_code,
       line_item_usage_type   AS usage_type,
       line_item_operation    AS operation,
       MAX(line_item_line_item_description)  AS price_desc,
       ROUND(SUM(line_item_usage_amount),2)   AS qty,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_product_code = 'AmazonEC2'
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1,2,3
ORDER BY cost DESC
LIMIT 30;
description 用 MAX() 包住 它不参与分组,但同组内基本一致,用 MAX() 取一条就能把单价文案带出来。
16

EC2 的钱到底花在哪(分类归桶)

破除「EC2 = 实例」的错觉
SELECT CASE
         WHEN line_item_usage_type LIKE '%BoxUsage%'        THEN '1-按需实例'
         WHEN line_item_usage_type LIKE '%SpotUsage%'       THEN '2-Spot 实例'
         WHEN line_item_usage_type LIKE '%EBS:VolumeUsage%' THEN '3-EBS 卷'
         WHEN line_item_usage_type LIKE '%EBS:Snapshot%'    THEN '4-EBS 快照'
         WHEN line_item_usage_type LIKE '%NatGateway%'      THEN '5-NAT Gateway'
         WHEN line_item_usage_type LIKE '%DataTransfer%'    THEN '6-流量'
         WHEN line_item_usage_type LIKE '%ElasticIP%'       THEN '7-弹性 IP'
         ELSE '9-其他'
       END AS bucket,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_product_code = 'AmazonEC2'
GROUP BY 1
ORDER BY bucket;
典型结论 很多团队跑完发现「EC2」里有 20–35% 根本不是实例,而是没删的 EBS 卷、堆积的快照、忘关的 NAT Gateway。 这几项的优化难度远低于动实例规格。
17

流量费用分类拆解

最容易被忽略的隐藏成本
SELECT CASE
         WHEN line_item_usage_type LIKE '%AZ-DataTransfer%' THEN '跨 AZ(同区域)'
         WHEN line_item_usage_type LIKE '%DataTransfer-Out%' THEN '出到互联网'
         WHEN line_item_usage_type LIKE '%DataTransfer-In%'  THEN '入向(多为免费)'
         ELSE '跨区域 / 其他'
       END AS transfer_kind,
       line_item_usage_type,
       ROUND(SUM(line_item_usage_amount),2)   AS gb,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_type LIKE '%DataTransfer%'
GROUP BY 1,2
ORDER BY cost DESC;
18

有效单价 vs 官网单价

验证折扣是否真的生效
-- 金额 ÷ 用量 = 实际有效单价,和 description 里的官网价对比
SELECT line_item_usage_type AS usage_type,
       MAX(line_item_line_item_description) AS list_price_desc,
       ROUND(SUM(line_item_usage_amount),2) AS qty,
       ROUND(SUM(pricing_public_on_demand_cost)
             / NULLIF(SUM(line_item_usage_amount),0),6) AS list_rate,
       ROUND(SUM(line_item_net_unblended_cost)
             / NULLIF(SUM(line_item_usage_amount),0),6) AS effective_rate
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_product_code = 'AmazonEC2'
GROUP BY 1
HAVING SUM(line_item_usage_amount) > 0
ORDER BY qty DESC
LIMIT 25;
只在同单位内做除法 不同 usage_type 的单位不同(Hrs / GB-Mo / Requests),跨类型算平均单价没有意义。 所以这条按 usage_type 分组,而不是按服务。
19

用 description 关键词捞特定计费项

找 License、找特定档位
-- description 是自由文本,适合做关键词排查,不适合做稳定分组键
SELECT service,
       line_item_line_item_description AS description,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND (line_item_line_item_description LIKE '%Windows%'
    OR line_item_line_item_description LIKE '%SQL Server%')
GROUP BY 1,2
ORDER BY cost DESC;
其他好用的关键词 %Multi-AZ% 查高可用溢价 · %provisioned% 查预置容量 · %Availability Zones% 查跨 AZ 流量 · %first%TB% 查阶梯定价档位。
知道钱花在什么计量项上 → 下一组回答「这钱该记到哪个团队头上」。

第 5 组 · 标签与成本归属(20–24)

目标:把技术费用翻译成业务费用。主角是三个标签列 resource_tags_user_projectresource_tags_user_service_nameresource_tags_user_name

标签列的两个前提 ① 标签必须在账单控制台激活为成本分摊标签,否则整列为空; ② 激活只对之后的数据生效,不会回填历史。
未打标签的行是空字符串,不是 NULL,所以本组统一用 NULLIF(col,'') 兜底。
20

按 Project 标签汇总(含未打标签)

最基础的业务视角账单
SELECT COALESCE(NULLIF(resource_tags_user_project,''),'(未打 Project)') AS project,
       ROUND(SUM(line_item_unblended_cost),2)     AS unblended,
       ROUND(SUM(line_item_net_unblended_cost),2) AS net
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1
ORDER BY net DESC;
一定要保留「未打标签」这一行 把它过滤掉,报表看起来很干净,但合计对不上账单,而且会掩盖治理问题。
21

业务服务标签 × AWS 服务 交叉表

看一个业务模块的技术构成
SELECT COALESCE(NULLIF(resource_tags_user_service_name,''),'(未打)') AS biz_service,
       service AS aws_service,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1,2
ORDER BY biz_service, cost DESC;
为什么值得单独看 service 是 AWS 的服务,service_name 标签是你自己的业务服务。 两者交叉才能回答「订单服务的钱有多少花在数据库上」这类问题。
22

三个标签的覆盖率

量化治理进度,可做月度 KPI
SELECT ROUND(SUM(line_item_unblended_cost),2) AS total_cost,
       ROUND(100.0 * SUM(CASE WHEN resource_tags_user_project <> ''
                              THEN line_item_unblended_cost ELSE 0 END)
             / NULLIF(SUM(line_item_unblended_cost),0),1) AS project_pct,
       ROUND(100.0 * SUM(CASE WHEN resource_tags_user_service_name <> ''
                              THEN line_item_unblended_cost ELSE 0 END)
             / NULLIF(SUM(line_item_unblended_cost),0),1) AS service_name_pct,
       ROUND(100.0 * SUM(CASE WHEN resource_tags_user_name <> ''
                              THEN line_item_unblended_cost ELSE 0 END)
             / NULLIF(SUM(line_item_unblended_cost),0),1) AS name_pct
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_resource_id <> ''   -- 只统计能打标签的行
  AND line_item_usage_start_date >= DATE '2026-07-01';
按金额算,不要按行数算 按行数算覆盖率会被大量小额行稀释;按金额加权才能反映「有多少钱是说不清归属的」。
23

未打 Project 标签的 Top 资源(治理清单)

可以直接发给团队的待办
SELECT account_name, service,
       line_item_resource_id AS resource_id,
       COALESCE(NULLIF(resource_tags_user_name,''),'(连 Name 都没有)') AS name_tag,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_resource_id <> ''
  AND COALESCE(resource_tags_user_project,'') = ''
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1,2,3,4
ORDER BY cost DESC
LIMIT 30;
带上 Name 标签是关键 光给一串 i-0abc… 没人认领;带上 Name 标签,团队一眼就知道是自己的机器。
24

单个 Project 的每日趋势

项目预算跟踪
SELECT DATE(line_item_usage_start_date) AS usage_day,
       COALESCE(NULLIF(resource_tags_user_service_name,''),'(未打)') AS biz_service,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND resource_tags_user_project = 'trading-core'
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1,2
ORDER BY usage_day, cost DESC;
归属清楚了 → 下一组落到单个资源,做具体优化动作。

第 6 组 · 资源级定位(25–27)

目标:把费用落到能直接动手的对象上。前提是创建导出时勾了 Include resource IDs

25

最烧钱的 Top 30 资源(带标签,方便找人)

优化清单的起点
SELECT line_item_resource_id AS resource_id,
       account_name, service,
       COALESCE(NULLIF(resource_tags_user_name,''),'-')         AS name_tag,
       COALESCE(NULLIF(resource_tags_user_project,''),'-')      AS project,
       COALESCE(NULLIF(resource_tags_user_service_name,''),'-') AS biz_service,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_resource_id <> ''
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1,2,3,4,5,6
ORDER BY cost DESC
LIMIT 30;
26

单个资源的费用构成与日趋势

搞清一台机器为什么贵
-- ① 这个资源的钱花在哪些计量项上
SELECT line_item_usage_type, line_item_operation,
       MAX(line_item_line_item_description)  AS description,
       ROUND(SUM(line_item_usage_amount),2)   AS qty,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_resource_id = 'i-0a1b2c3d4e5f67890'
  AND line_item_line_item_type = 'Usage'
GROUP BY 1,2
ORDER BY cost DESC;

-- ② 它是从哪天开始涨的
SELECT DATE(line_item_usage_start_date) AS usage_day,
       ROUND(SUM(line_item_usage_amount),2)   AS qty,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_resource_id = 'i-0a1b2c3d4e5f67890'
GROUP BY 1
ORDER BY usage_day;
一台 EC2 通常有多行 实例小时、EBS 卷、快照、流量各占一行。只看实例行会低估这台机器的真实成本。
27

归因缺口:多少钱落不到资源上

让报表能自证完整性
SELECT CASE WHEN COALESCE(line_item_resource_id,'') = ''
            THEN '无资源 ID' ELSE '有资源 ID' END AS has_resource,
       line_item_line_item_type AS line_type,
       ROUND(SUM(line_item_unblended_cost),2) AS cost
FROM cur
WHERE line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1,2
ORDER BY has_resource, cost DESC;
做资源级报表必跑这一条 前面所有带 resource_id <> '' 的查询都会丢掉这部分钱(税、Support、部分服务级用量)。 把缺口金额单独列出来,报表才对得上账单。
最后一组:把三个金额字段用起来,并输出给 BI。

第 7 组 · 折扣、净额与导出(28–30)

目标:用三个金额字段互相印证,最后产出一张能交给 BI 的宽表。

28

各服务折扣率(净额 vs 官网原价)

谈判和复盘的依据
SELECT service,
       ROUND(SUM(pricing_public_on_demand_cost),2) AS list_price,
       ROUND(SUM(line_item_unblended_cost),2)      AS paid,
       ROUND(SUM(line_item_net_unblended_cost),2)  AS net_paid,
       ROUND(100 * (1 - SUM(line_item_net_unblended_cost)
                        / NULLIF(SUM(pricing_public_on_demand_cost),0)),1) AS discount_pct
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1
HAVING SUM(pricing_public_on_demand_cost) > 0
ORDER BY list_price DESC;
折扣率低不一定是坏事 存储、流量类服务本身很少有折扣空间;重点看计算类服务的折扣率是否符合预期。
29

协议折扣落在了哪些计量项上

验证 EDP / PPA 是否按约定生效
-- unblended 减 net_unblended,就是协议类折扣的金额
SELECT service, line_item_usage_type,
       ROUND(SUM(line_item_unblended_cost),2)     AS unblended,
       ROUND(SUM(line_item_net_unblended_cost),2) AS net,
       ROUND(SUM(line_item_unblended_cost)
             - SUM(line_item_net_unblended_cost),2) AS discount_amount
FROM cur
WHERE line_item_line_item_type = 'Usage'
  AND line_item_usage_start_date >= DATE '2026-07-01'
GROUP BY 1,2
ORDER BY discount_amount DESC
LIMIT 25;
如果这列全是 0 说明你没有协议折扣,或者这张表没有净额数据 —— 这时 net_unblended 等于 unblended,两个字段用哪个都一样。
30

明细宽表:一次用上全部 19 个字段

交给 BI / Excel 的标准产出
-- 按天聚合,把小时级明细压到可接受的行数,同时保留全部分析维度
SELECT DATE(line_item_usage_start_date) AS usage_day,
       payer,
       line_item_usage_account_id      AS account_id,
       account_name,
       service,
       line_item_product_code          AS product_code,
       line_item_usage_type            AS usage_type,
       line_item_operation             AS operation,
       line_item_line_item_type        AS line_type,
       MAX(line_item_line_item_description) AS description,
       COALESCE(NULLIF(resource_tags_user_project,''),'untagged')      AS tag_project,
       COALESCE(NULLIF(resource_tags_user_service_name,''),'untagged') AS tag_service_name,
       COALESCE(NULLIF(resource_tags_user_name,''),'untagged')         AS tag_name,
       line_item_resource_id           AS resource_id,
       ROUND(SUM(line_item_usage_amount),4)            AS usage_amount,
       ROUND(SUM(line_item_unblended_cost),4)          AS unblended_cost,
       ROUND(SUM(line_item_net_unblended_cost),4)      AS net_unblended_cost,
       ROUND(SUM(pricing_public_on_demand_cost),4)     AS public_on_demand_cost
FROM cur
WHERE line_item_usage_start_date >= DATE '2026-07-01'
  AND line_item_usage_start_date <  DATE '2026-08-01'
GROUP BY 1,2,3,4,5,6,7,8,9,11,12,13,14
ORDER BY unblended_cost DESC;
三点注意GROUP BY跳过第 10 列,因为 description 用 MAX() 聚合了。
不过滤 line_item_line_item_type,而是把它作为一列输出,BI 侧自己决定口径 —— 这样一张表既能对账又能分析。
③ 带 resource_id 的行数会很大,给 BI 时可以先去掉这一列,行数通常能降一个量级。

用例地图:遇到问题该翻哪一组

你的问题去哪组关键字段
这个月账单为什么是这个数?第 1 组(1–5)line_item_line_item_type + 三个金额字段
费用什么时候涨的?涨了多少?第 2 组(6–10)line_item_usage_start_date
是哪个账户/团队涨的?第 3 组(11–14)payer · account_id · account_name
这笔钱具体买了什么?第 4 组(15–19)product_code · usage_type · operation · description
这钱该记到哪个业务头上?第 5 组(20–24)resource_tags_user_*
具体是哪台机器/哪个桶?第 6 组(25–27)line_item_resource_id
折扣生效了吗?怎么给 BI 出数?第 7 组(28–30)net_unblended_cost · public_on_demand_cost