Try Netice Own your app revenue data App Store and Google Play revenue, delivered to your warehouse or storage. Try free for 30 days No credit card required

App revenue SQL examples for BigQuery

Netice writes app revenue outputs into customer-owned BigQuery tables. This guide shows safe, read-only SQL examples for querying those tables: daily app-sales analytics in app_sales_daily and monthly platform finance rows in finance_unified where Finance Unified is configured.

Daily tableapp_sales_daily
Finance tablefinance_unified
Query typeRead-only SELECT
Core warningDaily ≠ finance

Which Netice BigQuery table should you query?

Netice app revenue data can appear in more than one BigQuery table because not all app-store revenue questions use the same source data. Daily App Sales and Finance Unified are intentionally separate outputs.

Daily App Sales uses the default BigQuery table app_sales_daily. It is built for operational analytics over Apple App Store and Google Play daily sales-style reporting. Apple daily rows come from Sales and Trends / Summary Sales style sources. Google daily rows come from Estimated Sales and subscription lifecycle style sources.

Finance Unified, where configured, uses the default BigQuery table finance_unified. It is a monthly platform finance output. Apple finance rows come from Apple financeReports. Google finance rows come from Google Play Earnings. It is not the daily app-sales table and should not be queried as if it were.

Table Source mode Use it for Do not use it for
app_sales_daily google_apple_app_sales Daily operational app revenue analytics, product/SKU rollups, source-report splits, country trends and data-completeness checks. Payout reconciliation, accounting close, audit, GAAP, IFRS, ASC 606, tax advice or bank reconciliation.
finance_unified finance_unified Monthly platform finance review where configured: Apple financeReports and Google Play Earnings. Daily product analytics replacement or row-level reconciliation to daily app-sales rows.

Before copying these SQL examples

These examples are read-only customer queries. They are for customer-side reporting and analysis only, not for modifying managed output tables, rebuilding destination-write behavior or running operational repair procedures.

All examples use synthetic identifiers such as example_project.example_dataset.app_sales_daily, example_project.example_dataset.finance_unified, com.example.app and premium_monthly. Use your own private project and dataset names when running queries in your warehouse. Keep real project IDs, datasets, table names, app IDs, SKUs, source paths, source row hashes, job IDs, task IDs, logs and customer data out of public examples and support snippets.

Daily App Sales field map

The daily table is designed around revenue_date, source context, report-currency estimates, native/local values, method fields, data completeness, lifecycle flags and provenance. Daily App Sales uses data_completeness for source-readiness context rather than is_final. Do not treat daily readiness as settlement finality.

Daily field group Representative fields Recommended SQL use
Date/source context revenue_date, platform, source, source_kind, source_report Trend reporting and source-family splits.
Product and geography app_id, item_id, item_name, country, subscription_period SKU, app, country and subscription-period rollups.
Report-currency estimates report_currency, estimated_gross, estimated_net, estimated_tax, estimated_fee BI-friendly daily analytics, not final finance truth.
Lifecycle filtering event_has_revenue, transaction_type Separate money-impacting rows from lifecycle-only rows.
Method context net_method, fee_method, tax_method Explain how values were sourced, estimated or derived.
Completeness and lineage data_completeness, ingested_at, source_row_hash, meta_json Coverage and provenance checks without exposing raw source rows.

Example 1: daily revenue trend by platform

This query is the standard starting point for daily operational analytics. It groups revenue by day, platform and report currency. It uses estimated_net because the table is a daily app-sales analytics table.

SELECT
  revenue_date,
  platform,
  report_currency,
  SUM(estimated_net) AS estimated_net_revenue,
  SUM(units) AS units
FROM `example_project.example_dataset.app_sales_daily`
WHERE revenue_date BETWEEN DATE '2026-04-01' AND DATE '2026-04-30'
  AND event_has_revenue = TRUE
GROUP BY revenue_date, platform, report_currency
ORDER BY revenue_date, platform, report_currency;

This is not payout reconciliation. It is a daily trend query for operational reporting.

Example 2: source-report breakdown

Source-report splits help analysts see which report families contributed rows. This is important because Apple Summary Sales, Apple subscription events, Google Play Estimated Sales and Google subscription lifecycle rows have different semantics.

SELECT
  source,
  platform,
  source_report,
  report_currency,
  COUNT(*) AS row_count,
  SUM(CASE WHEN event_has_revenue THEN estimated_net ELSE 0 END) AS estimated_net_revenue
FROM `example_project.example_dataset.app_sales_daily`
WHERE revenue_date BETWEEN DATE '2026-04-01' AND DATE '2026-04-30'
GROUP BY source, platform, source_report, report_currency
ORDER BY source, platform, source_report, report_currency;
Source report family Interpretation Boundary
ASC_SUMMARY_SALES Apple daily Summary Sales style rows. Not Apple financeReports.
ASC_SUBSCRIPTION_EVENT Apple subscription event rows where available. Not always revenue-impacting.
GP_ESTIMATED_SALES Google Play daily Estimated Sales style rows. Not Google Play Earnings.
GP_SUBSCRIPTIONS Google subscription lifecycle rows where available. Use event_has_revenue before summing money.

Example 3: revenue-impacting rows vs lifecycle-only rows

Subscription events can describe lifecycle changes without necessarily being revenue rows. The event_has_revenue flag helps keep lifecycle counts and money totals separate.

SELECT
  transaction_type,
  event_has_revenue,
  COUNT(*) AS row_count,
  SUM(CASE WHEN event_has_revenue THEN estimated_net ELSE 0 END) AS estimated_net_revenue
FROM `example_project.example_dataset.app_sales_daily`
WHERE revenue_date BETWEEN DATE '2026-04-01' AND DATE '2026-04-30'
GROUP BY transaction_type, event_has_revenue
ORDER BY event_has_revenue DESC, row_count DESC;

This query intentionally does not count every subscription event as money. Use it when building dashboards that show lifecycle activity beside revenue-impacting activity.

Example 4: product/SKU rollup

A common BI model groups daily app revenue by product or SKU. The example below uses the synthetic item ID premium_monthly. Keep real SKUs, product IDs and package names out of public examples.

SELECT
  item_id,
  item_name,
  platform,
  report_currency,
  SUM(estimated_net) AS estimated_net_revenue,
  SUM(units) AS units
FROM `example_project.example_dataset.app_sales_daily`
WHERE revenue_date BETWEEN DATE '2026-04-01' AND DATE '2026-04-30'
  AND event_has_revenue = TRUE
  AND item_id = 'premium_monthly'
GROUP BY item_id, item_name, platform, report_currency
ORDER BY estimated_net_revenue DESC;

Example 5: country rollup

Country reporting is useful for market-level analysis. Keep in mind that country availability and meaning depend on the source report family and row type.

SELECT
  country,
  platform,
  report_currency,
  SUM(estimated_net) AS estimated_net_revenue,
  SUM(units) AS units
FROM `example_project.example_dataset.app_sales_daily`
WHERE revenue_date BETWEEN DATE '2026-04-01' AND DATE '2026-04-30'
  AND event_has_revenue = TRUE
GROUP BY country, platform, report_currency
ORDER BY estimated_net_revenue DESC;

Example 6: data completeness coverage

data_completeness helps users understand source-readiness context for daily app-sales rows. It should not be described as settlement finality, payout finality or finance close.

SELECT
  revenue_date,
  data_completeness,
  COUNT(*) AS row_count,
  MAX(ingested_at) AS latest_ingested_at
FROM `example_project.example_dataset.app_sales_daily`
WHERE revenue_date BETWEEN DATE '2026-04-01' AND DATE '2026-04-30'
GROUP BY revenue_date, data_completeness
ORDER BY revenue_date, data_completeness;
Recommended use Unsafe interpretation
Source-readiness and freshness reporting. Final payout status.
Recent-window monitoring. Accounting close proof.
BI caveat/context for daily dashboards. Audit or tax finality.

Example 7: method-field coverage

Method fields help explain how daily values were sourced, estimated or derived. This is especially useful for fee and tax analysis because Apple and Google do not expose the same daily source facts.

SELECT
  source,
  platform,
  source_report,
  net_method,
  fee_method,
  tax_method,
  COUNT(*) AS row_count,
  SUM(estimated_net) AS estimated_net_revenue,
  SUM(estimated_fee) AS estimated_fee_amount,
  SUM(estimated_tax) AS estimated_tax_amount
FROM `example_project.example_dataset.app_sales_daily`
WHERE revenue_date BETWEEN DATE '2026-04-01' AND DATE '2026-04-30'
  AND event_has_revenue = TRUE
GROUP BY source, platform, source_report, net_method, fee_method, tax_method
ORDER BY source, platform, source_report, row_count DESC;

The goal is not to prove finance truth. The goal is to make analytical assumptions visible.

Finance Unified examples over finance_unified

The next examples query finance_unified. Use them only where Finance Unified is configured. The finance table is separate from app_sales_daily, and its fields should be interpreted through platform finance periods, event types, native/report currency and null-not-zero behavior.

Finance concept Representative fields Boundary
Source/report context source, platform, source_kind, source_report Separate Apple financeReports and Google Play Earnings from daily sources.
Period context fiscal_period, calendar_period, period_start, period_end Finance period semantics, not daily revenue dates.
Event taxonomy event_type, event_category, event_subtype Do not flatten fees, taxes, refunds and adjustments into ordinary sales.
Finance amounts native_net_proceeds, report_net_proceeds, fx_rate Null values remain null; real zero remains zero.
Finality is_final Derived finance finality, not audited accounting close.

Example 8: finance period rollup

This query groups Finance Unified rows by fiscal period, platform, source report and report currency. It is a finance-period summary, not a daily app-sales trend.

SELECT
  fiscal_period,
  platform,
  source_report,
  report_currency,
  is_final,
  SUM(report_net_proceeds) AS report_net_proceeds
FROM `example_project.example_dataset.finance_unified`
WHERE fiscal_period BETWEEN DATE '2026-04-01' AND DATE '2026-06-01'
GROUP BY fiscal_period, platform, source_report, report_currency, is_final
ORDER BY fiscal_period, platform, source_report, report_currency, is_final;

is_final is a Finance Unified derived field. It is not provider-guaranteed audit truth, accounting close, GAAP, IFRS, ASC 606, tax advice or bank reconciliation.

Example 9: finance null and zero coverage

Finance SQL should preserve the difference between unknown values and real zeros. The query below counts null report fields and real-zero values separately.

SELECT
  platform,
  source_report,
  event_type,
  COUNT(*) AS row_count,
  COUNTIF(report_net_proceeds IS NULL) AS report_net_proceeds_null_rows,
  COUNTIF(report_customer_charge IS NULL) AS report_customer_charge_null_rows,
  COUNTIF(fx_rate IS NULL) AS fx_rate_null_rows,
  COUNTIF(report_net_proceeds = 0) AS report_net_proceeds_real_zero_rows
FROM `example_project.example_dataset.finance_unified`
WHERE fiscal_period = DATE '2026-04-01'
GROUP BY platform, source_report, event_type
ORDER BY platform, source_report, event_type;

This is safer than hiding unknown finance values with blanket COALESCE(..., 0). A display-only dashboard may choose presentation defaults, but finance models should preserve null coverage.

Example 10: daily vs finance aggregate side-by-side

Daily App Sales and Finance Unified can be compared at a high-level aggregate, source-aware level. This does not mean every daily row reconciles to a finance row. Apple Summary Sales differs from Apple financeReports. Google Estimated Sales differs from Google Play Earnings.

WITH daily AS (
  SELECT
    DATE_TRUNC(revenue_date, MONTH) AS calendar_month,
    platform,
    report_currency,
    SUM(estimated_net) AS daily_estimated_net
  FROM `example_project.example_dataset.app_sales_daily`
  WHERE revenue_date BETWEEN DATE '2026-04-01' AND DATE '2026-04-30'
    AND event_has_revenue = TRUE
  GROUP BY calendar_month, platform, report_currency
),
finance AS (
  SELECT
    calendar_period AS calendar_month,
    platform,
    report_currency,
    SUM(report_net_proceeds) AS finance_report_net_proceeds
  FROM `example_project.example_dataset.finance_unified`
  WHERE calendar_period = DATE '2026-04-01'
  GROUP BY calendar_month, platform, report_currency
)
SELECT
  COALESCE(daily.calendar_month, finance.calendar_month) AS calendar_month,
  COALESCE(daily.platform, finance.platform) AS platform,
  COALESCE(daily.report_currency, finance.report_currency) AS report_currency,
  daily.daily_estimated_net,
  finance.finance_report_net_proceeds
FROM daily
FULL OUTER JOIN finance
  ON daily.calendar_month = finance.calendar_month
 AND daily.platform = finance.platform
 AND daily.report_currency = finance.report_currency
ORDER BY calendar_month, platform, report_currency;

This query uses COALESCE only to align dimension keys in the final projection. It does not convert finance amounts from null to zero.

FAQ

What is the default Netice Daily App Sales BigQuery table?

The default Daily App Sales BigQuery table is app_sales_daily.

Should I use estimated_net or report_net_proceeds?

Use estimated_net for Daily App Sales analytics in app_sales_daily. Use report_net_proceeds for Finance Unified period analysis in finance_unified where configured.

Can I filter Daily App Sales by is_final?

No. Daily App Sales uses data_completeness for source-readiness context rather than is_final. Do not treat daily readiness as settlement finality.

What does data_completeness mean?

data_completeness describes daily source-readiness or freshness context. It is not final payout, settlement, audit, tax or accounting close status.

How do I separate revenue rows from lifecycle rows?

Use event_has_revenue. This helps avoid summing subscription lifecycle-only events as money rows.

What is the difference between app_sales_daily and finance_unified?

app_sales_daily is daily operational analytics. finance_unified is monthly platform finance output where configured.

Can I compare Daily App Sales and Finance Unified totals?

You can compare them at an aggregate, source-aware level, but do not assume row-level reconciliation. They use different source families and period semantics.

Should missing finance amounts be converted to zero in SQL?

No. Unknown finance values should remain null unless a downstream model explicitly preserves the distinction between unknown and real zero.

Are these queries for modifying Netice-managed tables?

No. These are read-only reporting examples for customer-side analysis. They are not instructions for modifying managed output tables or running operational repair procedures.

Query app revenue outputs without losing source meaning

Netice app revenue tables are designed to keep daily analytics, monthly finance output, source reports, report currency, null handling and lineage context visible in your warehouse.

Review pricing Review security