Weiter zum Inhalt
Konto erstellen
oder
anmelden
Das Logo der Stripe-Dokumentation
/
KI fragen
Konto erstellen
Anmelden
Jetzt starten
Zahlungen
Finanzautomatisierung
Plattformen und Marktplätze
Geldmanagement
Entwickler-Tools
Jetzt starten
Zahlungen
Finanzautomatisierung
Jetzt starten
Zahlungen
Finanzautomatisierung
Plattformen und Marktplätze
Geldmanagement
Übersicht
Billing
Steuer
Berichte
Daten
    Übersicht
    Schema
    Nutzerspezifische Berichte
    Sigma-API
    Nutzerspezifische Berichte erstellen
    Mit Sigma Abfragen schreiben
    Daten innerhalb einer Organisation abfragen
    Stripe-Daten synchronisieren
    Data Pipeline
    Daten in ein Data Warehouse exportieren
    Daten in Cloud-Speicher exportieren
    Datenverwaltung
    Datenaktualität
    Anwendungsszenarien für Geschäfts- und Produktdaten
      Transaktionsdaten
      Daten zu Anfechtungen und Betrug
      Daten zu allen Gebühren
      Abrechnungsdaten
      Steuerdaten
      Daten zu verbundenen Konten
      Daten zur Kartenausstellung
    Externe Daten importieren
Start-up-Gründung
StartseiteFinanzautomatisierungDataBusiness and product data use cases

Rechnungsdaten abfragen

Verwenden Sie Sigma oder Data Pipeline, um Abrechnungsinformationen abzurufen.

Seite kopieren

Die Abrechnung besteht aus verschiedenen Komponenten, die zusammenarbeiten, um einmalige Rechnungen und regelmäßige Abrechnungen bereitzustellen, wobei verschiedene Aspekte der Abrechnungsdaten in einer Reihe von Tabellen verfügbar sind. Alle abrechnungsspezifischen Tabellen befinden sich im Abschnitt Abrechnung des Schemas, wobei die primären Tabellen subscriptions und invoices sind.

Um die Abrechnungsdaten genauer zu untersuchen, können Sie die zusätzlichen Tabellen verwenden, die die Komponenten von Abonnements und Rechnungen darstellen, z. B. prices, products oder coupons. Darüber hinaus ist die Tabelle customers ein wesentlicher Bestandteil der Abrechnung und enthält Daten, über die Sie möglicherweise Berichte erstellen müssen.

Abonnements

Jede Zeile in der Tabelle subscriptions liefert Daten zu einem einzelnen Subscription-Objekt – das sind die gleichen Informationen, die die API abruft oder im Stripe-Dashboard verfügbar sind. Sie können über jedes Abonnement Berichte erstellen, das Sie in Ihrem Konto erstellen.

Diese Tabelle ist der empfohlene Ausgangspunkt für die Erstellung von Berichten über Ihre aktuellen Abonnent/innen. Sie können diese Tabelle mit anderen zugehörigen Tabellen zusammenführen, sodass Sie Ihre Daten detaillierter untersuchen können.

Das folgende Beispiel ruft eine Liste von Abonnements ab, die als unbezahlt markiert wurden, sowie alle verfügbaren Kontaktinformationen für die Kundin/den Kunden.

select subscriptions.id, subscriptions.customer_id, customers.email from subscriptions inner join customers on customers.id = subscriptions.customer_id where subscriptions.status = 'unpaid' limit 5
IDcustomer_idE-Mail
sub_MQtkVFYEk4XDFtWcus_txXbCBvIVAGAtGVjenny.rosen@example.com
sub_eRFJrPf7WAlkxc2cus_zMr3g1EI4NBcDklnoah.wilson@example.com
sub_coOvSSiAWRoXhGXcus_GkeoXdCbsHdYi3Qjoshua.miller@example.com
sub_LMwQRlYLCxhRKlGcus_hqYDhzrLhrHc3c6madison.jackson@example.com
sub_m3K8QXqIKr1QvOscus_0pjz4VerhDBoWDxelijah.smith@example.com

Kund/innen

Daten über Customer-Objekte sind in der Tabelle customers enthalten (diese ist nicht Teil der Gruppe Abrechnung Tabellen). Er wird üblicherweise in abrechnungsbasierten Berichten verwendet und kann mit einer Reihe von Tabellen zusammengeführt werden. Es ist auch nützlich, wenn Sie Zahlungen mit gespeicherten Zahlungsinformationen erstellen.

Im folgenden Beispiel wird eine Liste von Kund/innen mit abonnements abgerufen, die sich derzeit im Testzeitraum befinden. Es ruft sowohl die ID als auch die E-Mail-Adresse für jede/n Kund/in ab.

select customers.id, customers.email, subscriptions.price_id from subscriptions inner join customers on customers.id = subscriptions.customer_id where subscriptions.status = 'trialing' limit 5
IDE-Mailprice_id
cus_WplNKEPApdR6mnNjenny.rosen@example.comruby-pro-522
cus_AZRgBgL2ibWMovjnoah.wilson@example.comruby-pro-522
cus_fqsPj5CM8VrXkMvrichard.jones@example.comgold-basic-221
cus_AjEUHgXnGKMgjwfmadison.jackson@example.comgold-basic-221
cus_9nqUhKvm1q3rE5Celijah.smith@example.comsilver-pro-498

Produkte und Preise

Produkte sind die Artikel, die Ihre Kund/innen mit einem Abonnement erwerben können. Preise sind an Produkte gebunden und umfassen Kosten, Abrechnungsintervall und Währung. Wenn Sie Daten aus der Tabelle subscriptions anzeigen, können Sie diese mit subscription_items zusammenführen. Darüber hinaus können Sie sie mit products.id zusammenführen, indem Sie die price_product_id aus dem Artikel verwenden.

Das folgende Beispiel gibt eine Liste aktiver Abonnements zusammen mit dem Produktnamen und seiner Zahlungsbeschreibung in der Abrechnung zurück:

active_subscription_products.sql
with active_subscriptions as ( select s.id as subscription_id, p.name as product_name, p.statement_descriptor from subscriptions s join subscription_items si on s.id = si.subscription_id join products p on si.price_product_id = p.id where s.status = 'active' ) select subscription_id, subscription_item_id, price_id, product_name, statement_descriptor from active_subscriptions order by 1,2
IDNamestatement_descriptor
sub_6svEt3JPYYTOS3bruby-pro-522Ruby Pro
sub_F0x2wx82XKUX1Gegold-basic-221Gold Basic
sub_QO6X7TQYcGomH40silver-pro-498Silver Pro
sub_BSFEKhTnVzMWUbodiamond-mid-244Diamond Mid
sub_BEbU8pg2It51kz9ruby-standard-196Ruby Standard

Preisstufen

Während Sie Preise mit Stufen in Ihren Abonnements verwenden, kann die Tabelle price_tiers spezifische Daten zu jeder Stufe bereitstellen. Wenn Sie beispielsweise Informationen zur Anfangsstufe Ihrer Abonnements erhalten möchten, einschließlich der Höchstmenge für die erste Stufe und des verwendeten Betrags für Einheiten, beziehen Sie sich auf die folgende Abfrage:

tiered_prices.sql
with subscription_item_prices as ( select si.subscription_id, si.price_id, p.currency from subscription_items si join prices p on si.price_id = p.id ), price_tier_details as ( select sp.subscription_id, pt.price_id, pt.upto, stringify_amount(sp.currency, pt.amount, '.') as tier_price, sp.currency from subscription_item_prices sp join price_tiers pt on sp.price_id = pt.price_id ) select ptd.subscription_id, ptd.price_id, ptd.upto, ptd.tier_price, ptd.currency from price_tier_details ptd order by ptd.subscription_id, ptd.price_id, ptd.upto asc
subscription_idprice_iduptotier_priceWährung
sub_I5IzQNgJV73JMvMprice_tkJWqcDj4ALLWep302,00USD
sub_wZIyWrBat6K5Tf9price_VCxwyCz8dLSD72Y601,00USD
sub_AAgrY5QJMoLoLeqprice_3GVKBxJiESRUwAO900.50USD

Rechnungen

Mit Rechnungen arbeiten

In unserer Rechnungsdokumentation finden Sie weitere Informationen zu Rechnungen, Rechnungspositionen und Rechnungsposten.

Die Tabelle invoices enthält Daten über einzelne Rechnung-Objekte. Für jedes Abonnement wird in regelmäßigen Abständen eine Rechnung erstellt, die den von der Kundin/vom Kunden geschuldeten Betrag darstellt. Dies beinhaltet automatisch den für das Abonnement erforderlichen Betrag und alle zusätzlichen Rechnungsposten, die möglicherweise erstellt wurden (aufgelistet als Einzelposten).

Rechnungen bestehen aus einzelnen (Rechnungs-)Posten. Diese Posten stellen alle Abonnements dar, die Kundinnen/Kunden in Rechnung gestellt werden, sowie Rechnungspositionen, die erstellt und auf die Rechnung angewendet wurden. Um eine Rechnung aufzuschlüsseln und jeden ihrer Posten zu analysieren, verwenden Sie die Tabelle invoice_line_items.

Die Spalte source_id dieser Tabelle enthält die ID des Abonnements (beispielsweise sub_VkugXnJJgU6pswO) oder der Rechnungsposition (beispielsweise ii_emnAJZKPXB0Ddp6), zu dem bzw. der der Posten gehört. Die Spalte source_type gibt an, ob der Posten ein Abonnement oder eine Rechnungsposition darstellt.

Im Gegensatz zu anderen Fremdschlüsseln wird die Spalte subscription der Tabelle invoice_line_items nicht immer ausgefüllt. Wenn die entsprechende Rechnungsposition für ein Abonnement steht, ist diese Spalte leer – ihre ID steht bereits in der Spalte source_id.

Rechnungsposten

Daten zu Rechnungsposten sind in der Tabelle invoice_items enthalten. Rechnungsposten werden üblicherweise verwendet, um einen zusätzlichen Betrag anzugeben (oder einen Betrag abzuziehen), der auf der nächsten Rechnung zu Beginn des nächsten Abrechnungszyklus angewendet wird. Sie würden beispielsweise einen Rechnungsposten erstellen, wenn Sie Ihrer Kundin/Ihrem Kunden in Rechnung stellen müssen, dass er sein monatliches Guthaben überschreitet, oder wenn Sie auf der nächsten Rechnung eine Gutschrift für nicht in Anspruch genommene Dienstleistung ausstellen müssen.

Im folgenden Beispiel werden alle Rechnungen und zugehörigen Zahlungs-IDs für ein bestimmtes Abonnement abgerufen.

select id, charge_id, amount_due from invoices where subscription_id = 'sub_ALJXL9gBYtv6GJ'
IDName
in_LfXbdb10zueBSfhch_XD8fMoB4WXQGUxs1999
in_DVELU1BitbjFCldch_c82EglrtYG85fqD1999
in_bj7RZhYuTFltUIy1999ch_jE4Eb9rNELL1p98
in_sqydMryUlOzkITx1999ch_uBec2V48fkoUIpy
in_0xjVLvcJRWO2znc1999ch_egrQFBWUwvnUdH4

Rechnungssummen und Rabatte

Die Rechnungszwischensumme ist die Summe aller Abonnements, Rechnungspositionen und Verrechnungen auf der Rechnung, bevor eventuelle Rabatte angewendet werden. Die Rechnungsgesamtsumme ist die Summe nach Anwendung von Rabatten und Steuern:

invoice.total = invoice.subtotal - discount + invoice.tax

Es gibt keine Spalte, um den Rabattbetrag auf einer Rechnung darzustellen. Stattdessen können Sie diesen berechnen, indem Sie die Rabattbeträge der Einzelposten zusammenfassen. Die folgende Abfrage gibt eine Liste der Rechnungen, das Start- und Enddatum und den gesamten Rabattbetrag für die Rechnung zurück.

invoice_discounts.sql
with invoices_with_discounts as ( select invoice_id, sum(amount) as total_discount_amount from invoice_line_item_discount_amounts group by invoice_id ) select i.id as invoice_id, i.period_start, i.period_end, stringify_amount(i.currency, ilda.total_discount_amount, '.') as total_discount_amount i.currency from invoices i join invoices_with_discounts ilda on i.id = ilda.invoice_id order by i.id
invoice_idperiod_startperiod_endtotal_discount_amountWährung
in_32ljk8LcsxHuM0x01.05.202401.06.202424,66USD
in_aRcqrPYvsgslJaK01.06.202401.07.202424,34USD
in_pcUsasfdXcfdE3301.04.202401.05.202445,96USD

Mit Rechnungsdaten und -zeiträumen arbeiten

Abonnement werden im Voraus abgerechnet. Dies bedeutet, dass der Kunde/die Kundin die Zahlung zu Beginn eines Abrechnungszyklus leistet. Dies wird im Wert period eines Posten dargestellt. Die Abrechnung für einen Kunden/eine Kundin mit einem monatlichen Abonnement erfolgt beispielsweise zu Beginn eines jeden Monats. Wenn sich der Kunde/die Kundin für cancel_at_period_end entscheidet, bleibt sein/ihr Abonnement bis zum Ende des Monats aktiv. Danach endet das Abonnement.

Die Werte period_start und period_end einer Rechnung geben an, wann Rechnungsposten erstellt wurden – sie geben nicht immer genau den Zeitraum an, für den Kundinnen/Kunden eine Rechnung gestellt wird. Wenn ein Kunde/eine Kundin beispielsweise am 1. eines jeden Monats eine Rechnung erhält und am 15. sein/ihr monatliches Kontingent überschreitet, können Sie einen Rechnungsposten für alle zusätzlichen Kosten erstellen, die dem Kunden/der Kundin in Rechnung gestellt werden. Dieser Rechnungsposten ist dann in der nächsten Rechnung enthalten, die am 1. des nächsten Monats erstellt wird. Bei der nächsten Rechnung ist das Datum für period_start der 15. des Vormonats: das Datum, an dem der zusätzliche Rechnungsposten ursprünglich erstellt wurde.

Nutzungsbasierte Abrechnung

Mit der nutzungsbasierten Abrechnung können Sie Ihren Kundinnen/Kunden Gebühren basierend auf der Nutzung Ihres Produkts oder Ihrer Dienstleistung in Rechnung stellen.

Abrechnungszähler

Ein Zähler-Objekt gibt an, wie Zählerereignisse über einen Abrechnungszeitraum hinweg zusammengefasst werden. Zählerereignisse stellen alle Aktionen dar, die Kundinnen/Kunden in Ihrem System durchführen (beispielsweise API-Anfragen). Zähler sind an Preise gebunden und bilden die Grundlage für das, was in Rechnung gestellt wird. Diese Objekte sind über die Tabelle billing_meters verfügbar.

Die folgende Abfrage gibt alle aktiven Abrechnungszähler zurück.

meters.sql
select id, status, display_name, default_aggregation_formula from billing_meters where status = 'ACTIVE' and livemode
IDStatusdisplay_namedefault_aggregation_formula
mtr_ICQ4fX8M9PihLfnAKTIValpaca_ai_tokenSUMME
mtr_3qSmMlKlhxcJcLuAKTIValpaca_ai_image_tokenANZAHL

Übersichte über Abrechnungszähler-Ereignisse

Ein Objekt des Typs Übersicht über Abrechnungszähler-Ereignisse stellt eine aggregierte Ansicht der Zählerereignisse eines Kunden/einer Kundin innerhalb eines bestimmten Zeitraums dar. Es gibt an, in welchem Umfang für einen Kunden/eine Kundin Verbrauch in diesem Zeitraum anfällt. Diese Objekte sind über die Tabelle billing_meter_event_summaries verfügbar. Stündliche Zusammenfassungen sind verfügbar, wie in der Spalte value_grouping_window angegeben.

Die folgende Abfrage gibt die Summe der Abrechnungszähler-Ereignisse für einen bestimmten Kunden/eine bestimmte Kundin zurück.

billing_meter_event_summaries.sql
select billing_meters.display_name, sum(billing_meter_event_summaries.aggregated_value) AS total_usage from billing_meter_event_summaries join billing_meters on billing_meters.id = billing_meter_event_summaries.meter_id where billing_meter_event_summaries.customer_id = 'cus_EDQkYj7P2Jf3sJ1' and billing_meter_event_summaries.start_time >= timestamp '2025-02-01 08:00' and billing_meter_event_summaries.end_time <= timestamp '2025-02-01 20:00' and value_grouping_window = 'hourly' group by display_name
display_nametotal_usage
alpaca_ai_token999373
alpaca_ai_image_token44

Ungültige Abrechnungszähler-Ereignisse

Ein Objekt des Typs Ungültiges Abrechnungszähler-Ereignis stellt ein Abrechnungszähler-Ereignis dar, das nicht erfolgreich validiert wurde. Diese Objekte sind über die Tabelle billing_meter_invalid_events verfügbar. Die zugehörige Tabelle billing_meter_invalid_events_payload enthält die Ereignisnutzlast des ursprünglichen Ereignisses.

Die folgende Abfrage gibt alle ungültigen Abrechnungszähler-Ereignisse für einen bestimmten Kunden/eine bestimmte Kundin zurück.

billing_meter_invalid_events.sql
SELECT billing_meter_invalid_events.id as event_id, billing_meter_invalid_events.error_code, billing_meter_invalid_events.error_message FROM billing_meter_invalid_events JOIN billing_meter_invalid_events_payload ON billing_meter_invalid_events_payload.event_id = billing_meter_invalid_events.id WHERE billing_meter_invalid_events_payload.key = 'stripe_customer_id' AND billing_meter_invalid_events_payload.value = 'cus_EDQkYj7P2Jf3sJ1'
event_iderror_codeerror_message
rv29N461HeP3WrmtovwlHIZR4emLMm8MMETER_NOT_FOUNDKein Zähler gefunden, der event_name mtr_oa7LIwohKiRiJKt entspricht.
40H4GHfphioiCKkB3PE3bJR3Zn0nNGXNMETER_NOT_FOUNDKein Zähler gefunden, der event_name mtr_q4HArw4MWfSdksI entspricht.

Gutscheine

Ein Coupon-Objekt stellt einen Rabatt in Form eines Betrags oder Prozentwerts dar, den Sie auf Abonnements oder für Kundinnen/Kunden anwenden können.

coupons.sql
select coupons.id, coupons.amount_off, coupons.percent_off from coupons where valid = false limit 5
IDamount_offpercent_off
10FF10
SUMMER2525
10FREE10
15OFF15
FALL3030

Rabatte

Bei einem Rabatt handelt es sich um die Anwendung eines Gutscheins, der durch ein Discount-Objekt dargestellt wird. Mit der folgenden Abfrage wird eine Liste der Abonnements und der damit verbundenen Rabatte und Gutscheine zurückgegeben:

discounts.sql
select subscriptions.id as subscription_id, t.discount_id, coupons.id as coupon_id from subscriptions cross join unnest(split(subscriptions.discounts, ',')) as t(discount_id) join discounts on discounts.id = t.discount_id join coupons on coupons.id = discounts.coupon_id limit 3
subscription_iddiscount_idcoupon_id
sub_sL2pLQ9JJshvgIwdi_urmFDORcmueypgh10OFF
sub_YjDqtlDenwH1xiBdi_cwwug02vcV4ZM3E25OFF
sub_HHL8yhvWejiRzgfdi_88F52nNQbwCfA9Q10FREE

Promo-Codes

Ein Promo-Code stellt einen von einer Kundin/einem Kunden einlösbaren Code für einen Gutschein dar. Die folgende Abfrage enthält eine Liste der Promo-Codes für einen bestimmten Gutschein und zeigt an, wie oft jeder Code eingelöst wurde:

promotion_codes.sql
select promotion_codes.id as promotion_code_id, promotion_codes.code as promotion_code, promotion_codes.times_redeemed from promotion_codes limit 3
promotion_code_idCodetimes_redeemed
promo_l7KjOL3bR7WnIUn10OFF1
promo_Z2DRIYprbbJGsXj25OFF2
promo_xLdxfMjwpYEiFAp10FREE3

Ereignisse bei der Änderung von Abonnement-Artikeln

Die Tabelle subscription_item_change_events verfolgt Änderungen an Abonnement-Objekten, die sich auf den monatlich wiederkehrenden Umsatz (MRR) und die Abonnementmengen auswirken. Verwenden Sie diese Tabelle, um den MRR für einzelne Kundinnen/Kunden, Produkte und Pläne zu berechnen und benutzerdefinierte Metrikdefinitionen für Ihre Geschäftsmodelle zu erstellen sowie Änderungen der Abonnementmengen zu verfolgen.

Vorsicht

Diese Tabelle enthält aktuellere Daten als die Quelle, aus der die MRR-Metriken in der Abrechnungsübersicht im Stripe Dashboard stammen. Dies bedeutet, dass die Daten für den MRR des letzten und des aktuellen Tages hier genauer sein könnten und von dem abweichen könnten, was Sie im Dashboard sehen.

local_event_timestamp and event_timestamp

Diese Tabelle enthält zwei Zeitstempelspalten:

  • event_timestamp: Dies ist der UTC-Zeitstempel.
  • local_event_timestamp: Dieser Zeitstempel befindet sich in Ihrer lokalen Zeitzone, in der Regel der Zeitzone der Person, die Ihr Stripe-Konto erstellt hat.

Währung

Hier finden Sie die Abrechnungswährung des Abonnementartikels als dreibuchstabigen ISO-Währungscode in Kleinbuchstaben. Die Währung muss eine sein, die Stripe unterstützt.

mrr_change

Die Spalte mrr_change zeigt die positiven oder negativen Auswirkungen eines Ereignisses auf Ihren MRR in der Nebeneinheit der Abrechnungswährung des Abonnements (zum Beispiel Cent für USD).

quantity_change

Die Spalte quantity_change zeigt die zugehörige positive oder negative Änderung der Menge eines Abonnement-Artikels, den eine Kundin/ein Kunde abonniert.

event_type

EreignistypDefinition
ACTIVE_STARTDer Abonnementposten hat begonnen, zum MRR beizutragen.
ACTIVE_ENDDer Abonnementposten hat aufgehört, zum MRR beizutragen.
ACTIVE_UPGRADEDer MRR-Beitrag des Abonnementartikels hat sich erhöht. Dies kann passieren, wenn der Preis eines Abonnementartikels oder die Menge dieses Abonnementartikels steigt.
ACTIVE_DOWNGRADEDer MRR-Beitrag des Abonnementartikels hat sich verringert. Dies kann passieren, wenn der Preis eines Abonnementartikels oder die Menge dieses Abonnementartikels sinkt.
ACTIVE_QUANTITY_INCREASEDie Menge des Abonnement-Artikels hat sich erhöht, der MRR ist hiervon jedoch nicht betroffen. Dies kann passieren, wenn Sie eine gestaffelte Preisgestaltung verwenden und die Menge über einem bestimmten Schwellenwert liegen muss, bevor sich der Preis ändert.
ACTIVE_QUANTITY_DECREASEDie Menge des Abonnement-Artikels hat sich verringert, der MRR ist hiervon jedoch nicht betroffen. Dies kann passieren, wenn Sie eine gestaffelte Preisgestaltung verwenden und die Menge unter einen bestimmten Schwellenwert fallen muss, bevor sich der Preis ändert.

Notiz

Einige Nutzeraktionen können mehrere Ereignisse erstellen, sodass Sie ein Ereignis mit einem event_type von ACTIVE_END für einen Posten und dann sofort ein Ereignis mit einem event_type von ACTIVE_START für einen anderen Posten für dieselbe subscription_id sehen können.

Andere Spalten

Andere Spalten (product_id, price_id, customer_id, subscription_id und subscription_item_id) enthalten IDs im Zusammenhang mit dem Ereignis für die Änderung von Abonnementposten.

Beispielabfragen

Weitere und aktuelle Beispiele finden Sie im Abschnitt „Abonnements“ der Abfragevorlagenbibliothek in der Sigma-Seitenleiste.

Um den monatlich wiederkehrenden Umsatz (MRR) und die Anzahl der aktiven Abonnenten/Abonenntinnen anhand dieser Tabelle zu berechnen, müssen Sie Fensterfunktionen verwenden. Wenn Sie Kundinnen/Kunden haben, die verschiedene Währungen verwenden, müssen Sie außerdem Wechselkursberechnungen durchführen. Die Berechnung hat zum Ziel, den monatlichen MRR und die Entwicklung der aktiven Abonnenten/Abonnentinnen zu verfolgen und unterscheidet dabei zwischen Neuzugängen, Reaktivierungen, Erweiterungen, Minderungen und Abwanderung. Die endgültigen Ergebnisse werden in untergeordneten Währungseinheiten wie Cent (bei USD) dargestellt.

WITH ts_grouped_sub_item_events AS ( SELECT local_event_timestamp, customer_id, currency, sum(mrr_change) AS mrr_change FROM subscription_item_change_events GROUP BY 1, 2, 3 ), ts_grouped_sub_item_events_with_mrr AS ( SELECT *, date_trunc( 'day', date(local_event_timestamp) ) AS local_event_date, -- Stripe defines an "active subscriber" as a customer with non-zero MRR. -- Therefore instead of summing up event_type to get subscription count (and its diff), -- We count the amount of revenue on each customer instead and later check its movement from / to zero sum(mrr_change) over ( PARTITION by customer_id ORDER BY local_event_timestamp ASC ) AS mrr, -- We count the # of times MRR has actually changed, and use nullif to ignore events that do not impact MRR -- Otherwise we may confuse between new vs. reactivation count(nullif(mrr_change, 0)) over ( PARTITION by customer_id ORDER BY local_event_timestamp ASC ) AS mrr_change_count FROM ts_grouped_sub_item_events ), ts_grouped_sub_item_events_with_previous_mrr AS ( SELECT *, coalesce( last_value(mrr) IGNORE nulls OVER ( PARTITION by customer_id ORDER BY local_event_timestamp ASC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ), 0 ) AS previous_mrr FROM ts_grouped_sub_item_events_with_mrr ), customer_events AS ( SELECT *, CASE WHEN mrr = 0 AND previous_mrr > 0 THEN 'ACTIVE_END' WHEN mrr > 0 AND previous_mrr = 0 AND mrr_change_count = 1 THEN 'ACTIVE_START' WHEN mrr > 0 AND previous_mrr = 0 AND mrr_change_count > 1 THEN 'REACTIVATE' WHEN mrr > previous_mrr THEN 'ACTIVE_UPGRADE' WHEN mrr < previous_mrr THEN 'ACTIVE_DOWNGRADE' ELSE NULL END AS cus_event_type FROM ts_grouped_sub_item_events_with_previous_mrr ), date_grouped_customer_events AS ( SELECT local_event_date, currency, sum(mrr_change) AS mrr_change, sum( CASE cus_event_type WHEN 'ACTIVE_START' THEN mrr_change ELSE 0 END ) AS new_mrr, sum( CASE cus_event_type WHEN 'REACTIVATE' THEN mrr_change ELSE 0 END ) AS reactivation_mrr, sum( CASE cus_event_type WHEN 'ACTIVE_UPGRADE' THEN mrr_change ELSE 0 END ) AS expansion_mrr, sum( CASE cus_event_type WHEN 'ACTIVE_DOWNGRADE' THEN mrr_change ELSE 0 END ) AS contraction_mrr, sum( CASE cus_event_type WHEN 'ACTIVE_END' THEN mrr_change ELSE 0 END ) AS churn_mrr, sum( CASE WHEN mrr = 0 AND previous_mrr > 0 THEN -1 WHEN mrr > 0 AND previous_mrr = 0 THEN 1 ELSE 0 END ) AS active_subscribers_change, sum( CASE cus_event_type WHEN 'ACTIVE_END' THEN 1 ELSE 0 END ) AS churned_subscribers, sum( CASE cus_event_type WHEN 'ACTIVE_START' THEN 1 ELSE 0 END ) AS new_subscribers, sum( CASE cus_event_type WHEN 'REACTIVATE' THEN 1 ELSE 0 END ) AS reactivated_subscribers FROM customer_events GROUP BY 1, 2 ), -- Prepare the multi dimensional table with all days + currency combinations and conversion rate metadata -- note that exchange_rates_from_usd contains one row for every date from 2010-01-07 until today -- which is why we don't need to generate a separate date series for the full table dates_with_rate_per_usd AS ( SELECT -- We use previous day's closing rates in precomputed metrics date - INTERVAL '1' DAY AS fx_date, cast( json_parse(buy_currency_exchange_rates) AS map(varchar, double) ) AS rate_per_usd FROM exchange_rates_from_usd ), currencies AS ( SELECT DISTINCT(currency) FROM subscription_item_change_events ), first_default_currency AS ( SELECT default_currency FROM accounts WHERE default_currency IS NOT NULL LIMIT 1 ), dates_x_currencies_with_conversion_rate AS ( SELECT fx_date as local_date, currency, default_currency, 1 / rate_per_usd [currency] * rate_per_usd [coalesce(default_currency, 'usd')] AS conversion_rate FROM dates_with_rate_per_usd CROSS JOIN currencies CROSS JOIN first_default_currency ORDER BY 1, 2 ), daily_metrics_by_currency AS ( SELECT dpc.local_date, dpc.currency, dpc.conversion_rate, coalesce( sum(mrr_change) over ( PARTITION by dpc.currency ORDER BY dpc.local_date ASC ), 0 ) AS mrr, coalesce( round( sum(mrr_change) over ( PARTITION by dpc.currency ORDER BY dpc.local_date ASC ) * dpc.conversion_rate ), 0 ) AS converted_mrr, coalesce(round(new_mrr * conversion_rate), 0) AS converted_new_mrr, coalesce(round(reactivation_mrr * conversion_rate), 0) AS converted_reactivation_mrr, coalesce(round(expansion_mrr * conversion_rate), 0) AS converted_expansion_mrr, coalesce(round(contraction_mrr * conversion_rate), 0) AS converted_contraction_mrr, coalesce(round(churn_mrr * conversion_rate), 0) AS converted_churn_mrr, coalesce(dgce.mrr_change, 0) AS mrr_change, coalesce(dgce.new_mrr, 0) AS new_mrr, coalesce(dgce.reactivation_mrr, 0) AS reactivation_mrr, coalesce(dgce.expansion_mrr, 0) AS expansion_mrr, coalesce(dgce.contraction_mrr, 0) AS contraction_mrr, coalesce(dgce.churn_mrr, 0) AS churn_mrr, coalesce( sum(active_subscribers_change) over ( PARTITION by dpc.currency ORDER BY dpc.local_date ASC ), 0 ) AS active_subscribers, coalesce(dgce.active_subscribers_change, 0) AS active_subscribers_change, coalesce(dgce.churned_subscribers, 0) AS churned_subscribers, coalesce(dgce.new_subscribers, 0) AS new_subscribers, coalesce(dgce.reactivated_subscribers, 0) AS reactivated_subscribers FROM dates_x_currencies_with_conversion_rate dpc LEFT JOIN date_grouped_customer_events dgce ON dpc.local_date = dgce.local_event_date AND dpc.currency = dgce.currency ), daily_metrics AS ( SELECT local_date, sum(converted_mrr) AS mrr, sum(converted_new_mrr) AS new_mrr, sum(converted_reactivation_mrr) AS reactivation_mrr, sum(converted_expansion_mrr) AS expansion_mrr, sum(converted_contraction_mrr) AS contraction_mrr, sum(converted_churn_mrr) AS churn_mrr, -- Customer can only have active subscription in a single currency at a time, as a result this does not result in over-counting subscriber changes -- This also matches the precomputed metrics logic in billing dashboard / CSV download sum(active_subscribers) AS active_subscribers, sum(churned_subscribers) AS churned_subscribers, sum(new_subscribers) AS new_subscribers, sum(reactivated_subscribers) AS reactivated_subscribers FROM daily_metrics_by_currency GROUP BY 1 ), daily_metrics_with_derived AS ( SELECT *, mrr - lag(mrr) over ( ORDER BY local_date ) - new_mrr - reactivation_mrr - expansion_mrr - contraction_mrr - churn_mrr AS fx_adjustment_mrr, lag(mrr) over ( ORDER BY local_date ) AS previous_mrr FROM daily_metrics ), -- Turn daily into monthly metrics monthly_metrics_with_derived AS ( SELECT date_trunc('month', local_date) AS local_month_start, max_by(mrr, local_date) AS ending_mrr, sum(new_mrr) AS new_mrr, sum(reactivation_mrr) AS reactivation_mrr, sum(expansion_mrr) AS expansion_mrr, sum(contraction_mrr) AS contraction_mrr, sum(churn_mrr) AS churn_mrr, sum(fx_adjustment_mrr) AS fx_adjustment_mrr, max_by(active_subscribers, local_date) AS ending_subscribers, sum(churned_subscribers) AS churned_subscribers, sum(new_subscribers) AS new_subscribers, sum(reactivated_subscribers) AS reactivated_subscribers FROM daily_metrics_with_derived GROUP BY 1 ) SELECT local_month_start, ending_mrr - fx_adjustment_mrr - churn_mrr - contraction_mrr - expansion_mrr - reactivation_mrr - new_mrr AS beginning_mrr, new_mrr, reactivation_mrr, expansion_mrr, contraction_mrr, churn_mrr, fx_adjustment_mrr, ending_mrr, -- Churned subscribers is a positive number in CSV reports instead of negative for churn / contraction mrr ending_subscribers - (-1 * churned_subscribers) - reactivated_subscribers - new_subscribers AS beginning_subscribers, new_subscribers, reactivated_subscribers, churned_subscribers, ending_subscribers FROM monthly_metrics_with_derived ORDER BY 1 DESC
local_month_startbeginning_mrrnew_mrrreactivation_mrrexpansion_mrrcontraction_mrrchurn_mrrfx_adjustment_mrrending_mrrbeginning_subscribersnew_subscribersreactivated_subscriberschurned_subscribersending_subscribers
01.05.2024100072149104000040000000100216149930012
01.04.20241000651497180000-1800100072149730012
01.03.2024100066099124000-1074010006514972027
01.02.20241000660991000000-1000010006609971017
01.01.20241000381022921601998-175-3042010006609954 $027
01.12.202310003810200000010003810250005
01.11.20231000371021000000001000381024 $1005
01.10.20231000371020000001000371024 $0004 $
01.09.20231000371020000001000371024 $0004 $
01.08.20231000339020050000-1800010003710250014 $
01.07.20231000370650000-3159-410003390260015
01.06.202310003640235336900-274211000370656134 $6
01.05.20231000348982748030437-83-3159801000364027304 $6
01.04.2023100034065933000-100010003489862017
01.03.202310000271531350000001000340654 $2006
01.02.20231000060486086060880-15507010000271552034 $
01.01.20231000060483043000-3043010000604851015
01.12.20221001521342591001363600-30000-1505574-22100006048960105
01.11.2022100178232486883333621878-10600-68939701001521347161159
01.10.202210003619313633312000020600-10000-124894010017823274 $267
War diese Seite hilfreich?
JaNein
Benötigen Sie Hilfe? Kontaktieren Sie den Kundensupport.
Nehmen Sie an unserem Programm für frühzeitigen Zugriff teil.
Schauen Sie sich unser Änderungsprotokoll an.
Fragen? Sales-Team kontaktieren.
LLM? Lesen Sie llms.txt.
Unterstützt von Markdoc