面向具备 Cloud 与 SQL 基础的读者,四步读懂 AWS 成本与使用量报告。
AWS 最细粒度的账单数据集:把每笔费用按「产品 × 使用类型 × 操作 × 时间」拆成明细行,可细到小时级 + 单个资源。
lineItem/UnblendedCostline_item_unblended_cost配置 CUR 涉及三层权限,看懂这张图就理清了全局。
"Action": [ "cur:PutReportDefinition", "cur:DescribeReportDefinitions", "cur:ModifyReportDefinition", "cur:DeleteReportDefinition", // CUR 2.0 额外需要 "bcm-data-exports:CreateExport", "bcm-data-exports:GetExport", // 建桶还需 s3:CreateBucket / PutBucketPolicy ]
CUR 由账单服务把文件写进你的桶,Principal 必须是 billingreports.amazonaws.com。
"Principal": { "Service": "billingreports.amazonaws.com" }, "Action": [ "s3:GetBucketAcl", "s3:GetBucketPolicy", // 读桶属性 "s3:PutObject" // 写入报告文件 ], "Resource": "arn:aws:s3:::your-cur-bucket(/*)"
字段有上百个,但不用背。先看懂「一行数据」,剩下的都是它的扩展。
Team=payment。标签需在账单控制台激活为成本分摊标签后才会出现时间 + 账户 + 计量项 + 用量×单位 + 费用 + 标签 + 行类型。
任何 CUR 查询,本质都是「选几个维度 GROUP BY,把费用 SUM 起来」。
本文全部采用 CUR 2.0(Data Exports)命名:全小写 snake_case,表名 COST_AND_USAGE_REPORT。
遇到不认识的字段,先看前缀就知道它回答什么问题。
resource_tags),也可以在导出时选择把嵌套 key 摊平成独立列。
官方把字段分成 13 组,见 AWS 官方 CUR 2.0 表字典。
这是 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 还是别的形式)会随导出配置不同,
先跑一句 SHOW COLUMNS FROM cur 或 SELECT * FROM cur LIMIT 1 对一遍,比照文档更可靠。
同一张表里混着「真实用量」「税」「抵扣」「预付承诺」等不同性质的行。不区分类型直接 SUM,结果一定是错的。
| 类型 | 金额正负 | 它代表什么 | 该看哪个费用字段 |
|---|---|---|---|
| Usage | 正 | 按需用量,最主要的一类行 | unblended_cost |
| Tax | 正 | 税费(如日本消费税) | unblended_cost |
| Fee | 正 | 一次性/固定费用,如 RI 全额预付、Support 费 | unblended_cost |
| Credit | 负 | AWS 给的抵扣券、活动信用 | unblended_cost |
| Refund | 负 | 退款 | unblended_cost |
| RIFee | 正 | RI 的月度承诺费(不是用量!按月摊到每小时记账) | unblended_cost |
| DiscountedUsage | 通常 0 | 被 RI 覆盖的用量。钱已在 RIFee 里付过,所以这行 unblended 是 0 | reservation_effective_cost |
| SavingsPlanCoveredUsage | 通常 0 | 被 SP 覆盖的用量,同理 | savings_plan_savings_plan_effective_cost |
| SavingsPlanRecurringFee | 正 | SP 的小时承诺费 | unblended_cost |
| SavingsPlanNegation | 负 | 抵消 SP 覆盖行的记账项,避免重复计费 | unblended_cost |
| BundledDiscount EdpDiscount PrivateRateDiscount | 负 | 各类协议折扣(EDP/PPA 等) | unblended_cost |
SUM(unblended_cost) 全类型都要,别过滤。line_item_line_item_type='Usage',避免抵扣行干扰排名。
product_product_name 是给人看的显示名(会变、有空格),
line_item_product_code 是稳定的服务代码,写 WHERE 条件优先用它。
| line_item_product_code | product_product_name | 这个 code 底下都装了什么 |
|---|---|---|
| AmazonEC2 | Amazon Elastic Compute Cloud | 不只是实例:EC2 实例 + EBS 卷 + 快照 + NAT Gateway + 弹性 IP + 区域内/跨 AZ 流量 |
| AmazonS3 | Amazon Simple Storage Service | 存储容量 + 请求次数 + 取回 + 生命周期转换 |
| AmazonRDS | Amazon Relational Database Service | 数据库实例 + 存储 + IOPS + 备份 + 快照导出 |
| AWSELB | Elastic Load Balancing | ALB / NLB / CLB 的小时费 + LCU |
| AWSLambda | AWS Lambda | 请求数 + GB-Second + 预置并发 |
| AmazonCloudFront | Amazon CloudFront | 出站流量 + 请求数(按边缘位置分区域) |
| AWSDataTransfer | AWS Data Transfer | 跨区域流量,和 EC2 内部的区域内流量分开记 |
| AmazonElastiCache | Amazon ElastiCache | 缓存节点小时费 + 备份 |
| awskms | AWS Key Management Service | 注意:部分 code 是全小写的,写死字符串前先 SELECT DISTINCT 确认 |
| AWSSupportBusiness | AWS Support (Business) | Support 费,通常 line_item_line_item_type = Fee,无 resource_id |
下面每张卡片就是 CUR 里一行的真实字段组合:product_code 定服务、
usage_type 定计量项、operation 定细分、
description 给单价、resource_id 落到具体资源。
Lambda-Request 记请求数,两行合起来才是总成本LCUUsage 行记容量单位product_code + usage_type + operation 三件套。
| 资源类型 | 形态 | 示例 |
|---|---|---|
| EC2 实例 | 裸 ID | i-0a1b2c3d4e5f67890 |
| EBS 卷 / 快照 | 裸 ID | vol-0c1d2e3f4a5b6c7d8 · snap-0e2f3a4b5c6d7e8f9 |
| S3 桶 | 名称 | my-app-logs-bucket |
| RDS / Lambda / ALB / NAT / DynamoDB | 完整 ARN | arn:aws:rds:ap-northeast-1:222222222222:db:prod-mysql-01 |
| Tax / Fee / Support / Credit 等非资源行 | 空 | ''(空字符串,不是 NULL) |
element_at(split(line_item_resource_id,'/'),-1) 或
split_part(line_item_resource_id,':',-1) 取最后一段。line_item_resource_id <> '',只写 IS NOT NULL 会漏。
| 场景 | line_item_line_item_type | unblended | effective_cost | public_on_demand |
|---|---|---|---|---|
| 纯按需跑 1 小时 | Usage | $0.124 | 空 | $0.124 |
| 被 RI 覆盖的这 1 小时 | DiscountedUsage | $0.00 | $0.062 | $0.124 |
| 该 RI 的月度承诺费 | RIFee | $45.26 | 空 | 空 |
全部只用下面这 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 |
业务归属三件套:项目 / 业务服务 / 资源名。对应标签 Project、service_name、Name |
| 资源 | 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 一定要给上下界,别全表扫。billing_period 或
bill_billing_period_start_date),WHERE 里带上它,扫描量和费用都会大幅下降。
目标:先让总数和账单对上,再往下拆。顺序不能颠倒 —— 总数不对,后面的排名全是错的。
-- 关键:不要过滤 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';
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';
pricing_public_on_demand_cost 只在用量行上有值,混入税费和抵扣行会把折扣率算歪。
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;
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;
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 是付款账户,整张表基本同一个值;
line_item_usage_account_id 才是真正产生费用的成员账户。拆账永远用后者。
如果你的表已有 account_id 友好列,直接用它,效果一样。
目标:回答「什么时候涨的、涨在哪」。所有查询都围绕 line_item_usage_start_date 展开。
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;
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;
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;
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;
-- 从用例 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;
目标:在多账户组织里把钱分清楚。主角是 payer / account_id / account_name。
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 () 是聚合套窗口,一次查询就能同时拿到明细和全局合计,不用子查询。
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;
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;
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;
目标:把「EC2 花了 1.2 万」拆成可以动手优化的条目。主角是 product_code + usage_type + operation + description。
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;
MAX() 取一条就能把单价文案带出来。
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;
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;
-- 金额 ÷ 用量 = 实际有效单价,和 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;
-- 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% 查阶梯定价档位。
目标:把技术费用翻译成业务费用。主角是三个标签列
resource_tags_user_project、
resource_tags_user_service_name、
resource_tags_user_name。
NULLIF(col,'') 兜底。
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;
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 标签是你自己的业务服务。
两者交叉才能回答「订单服务的钱有多少花在数据库上」这类问题。
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';
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;
i-0abc… 没人认领;带上 Name 标签,团队一眼就知道是自己的机器。
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;
目标:把费用落到能直接动手的对象上。前提是创建导出时勾了 Include resource IDs。
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;
-- ① 这个资源的钱花在哪些计量项上 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;
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 的宽表。
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;
-- 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;
net_unblended 等于 unblended,两个字段用哪个都一样。
-- 按天聚合,把小时级明细压到可接受的行数,同时保留全部分析维度 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() 聚合了。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 |