LW IT Solutions logo LW IT Solutions logo LW IT Solutions
« Blog-Übersicht /Digital Marketing/Tutorials / Tutorial: GA4-Einwilligungsstatus in BigQuery und Looker Studio
Diesen Artikel in anderen Sprachen lesen:

Tutorial: GA4-Einwilligungsstatus in BigQuery und Looker Studio

Tutorial: GA4-Einwilligungsstatus in BigQuery und Looker Studio
Inhalt
  1. 1. Kennzahl und Voraussetzungen
  2. 2. Dreißig abgeschlossene Kalendertage
  3. 3. Dashboard ohne irreführenden Trichter
  4. 4. Interpretation und Grenzen
  5. Fragen und Antworten
  6. Quellen

Ein Consent-Bericht aus GA4 beantwortet eine eng umrissene Frage: Welcher Anteil der exportierten Ereignisse trägt welchen Einwilligungsstatus? Ein Wert von 70 Prozent für analytics_storage = Yes bedeutet, dass 70 von 100 erfassten Ereignissen diesen Status tragen. Daraus folgt keine Bannerzustimmung von 70 Prozent der Besucher.

Dieses Tutorial erstellt einen täglichen Statusbericht in BigQuery und bereitet die Zählwerte für Looker Studio auf. Analytics-Speicherung und Werbespeicherung bleiben getrennt. Unbekannte Zustände und fehlende Tagestabellen bleiben sichtbar. Veränderungen liefern einen Ausgangspunkt für die Fehlersuche, aber keinen Beweis für einen Bannerfehler oder entgangene Conversions.

Tägliche Exportereignisse, getrennte Analytics- und Ads-Speicherzustände sowie gewichtete Dashboardanteile
Ereignisanteile beschreiben den Export; Bannerentscheidungen benötigen eine eigene Kennzahl.

1. Kennzahl und Voraussetzungen

Vorausgesetzt sind eine bestehende GA4-Verknüpfung mit BigQuery, aktivierter täglicher Export sowie Lese- und Abfragerechte. Consent Mode muss die vorgesehenen Standardwerte und Änderungen korrekt übertragen. Die Verknüpfung mit BigQuery rekonstruiert keine vergangenen Bannerentscheidungen.

Das Ereignisschema enthält privacy_info.analytics_storage und privacy_info.ads_storage. Dokumentierte Werte sind Yes, No und Unset. Die Abfrage sammelt zusätzlich Nullwerte und unerwartete Inhalte unter other. Ein nicht gesetzter Status ist keine ausdrückliche Ablehnung. Beide Felder bilden nicht sämtliche Consent-Mode-Einstellungen ab: Werbespeicherung unterscheidet sich von der Freigabe für Werbenutzerdaten und personalisierte Werbung.

Der Nenner umfasst alle exportierten Ereignisse der ausgewählten Tagestabellen. Ein aktiver Besuch liefert mehr Ereignisse als ein kurzer Besuch. Der Standardwert vor einer Bannerentscheidung kann vom späteren Status abweichen. Bei einer grundlegenden Implementierung fehlt blockierter Verkehr in GA4. Erweiterte Implementierungen können bei verweigerter Speicherung Pings ohne Cookies senden. Browserblockaden und Erfassungsfehler verursachen weitere Lücken. Eine Quote aus den vorhandenen Zeilen ergänzt diese fehlenden Daten nicht.

2. Dreißig abgeschlossene Kalendertage

Das Beispiel verwendet Europe/Warsaw; maßgeblich ist die Zeitzone der GA4-Property. Projekt und Dataset benötigen die passenden Namen. Das Ergebnis enthält eine Zeile pro Tag, beginnend vor 30 Tagen bis einschließlich gestern. Intraday-Tabellen und der laufende Tag bleiben ausgeschlossen.

SQL
-- Standard SQL. Replace project/dataset and property timezone.
WITH days AS (
  SELECT day FROM UNNEST(GENERATE_DATE_ARRAY(
    DATE_SUB(CURRENT_DATE('Europe/Warsaw'), INTERVAL 30 DAY),
    DATE_SUB(CURRENT_DATE('Europe/Warsaw'), INTERVAL 1 DAY))) AS day
), available AS (
  SELECT table_name FROM `project.analytics_XXXXXXXXX.INFORMATION_SCHEMA.TABLES`
  WHERE table_type = 'BASE TABLE'
    AND REGEXP_CONTAINS(table_name, r'^events_[0-9]{8}$')
), counts AS (
  SELECT PARSE_DATE('%Y%m%d', _TABLE_SUFFIX) AS day,
    COUNT(*) AS total_events,
    COUNTIF(privacy_info.analytics_storage = 'Yes') AS analytics_yes,
    COUNTIF(privacy_info.analytics_storage = 'No') AS analytics_no,
    COUNTIF(privacy_info.analytics_storage = 'Unset') AS analytics_unset,
    COUNTIF(COALESCE(privacy_info.analytics_storage NOT IN ('Yes','No','Unset'), TRUE)) AS analytics_other,
    COUNTIF(privacy_info.ads_storage = 'Yes') AS ads_yes,
    COUNTIF(privacy_info.ads_storage = 'No') AS ads_no,
    COUNTIF(privacy_info.ads_storage = 'Unset') AS ads_unset,
    COUNTIF(COALESCE(privacy_info.ads_storage NOT IN ('Yes','No','Unset'), TRUE)) AS ads_other
  FROM `project.analytics_XXXXXXXXX.events_*`
  WHERE _TABLE_SUFFIX BETWEEN
    FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE('Europe/Warsaw'), INTERVAL 30 DAY))
    AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE('Europe/Warsaw'), INTERVAL 1 DAY))
  GROUP BY day
)
SELECT d.day, a.table_name IS NOT NULL AS table_present,
  IF(a.table_name IS NULL, NULL, COALESCE(c.total_events, 0)) AS total_events,
  IF(a.table_name IS NULL, NULL, COALESCE(c.analytics_yes, 0)) AS analytics_yes,
  IF(a.table_name IS NULL, NULL, COALESCE(c.analytics_no, 0)) AS analytics_no,
  IF(a.table_name IS NULL, NULL, COALESCE(c.analytics_unset, 0)) AS analytics_unset,
  IF(a.table_name IS NULL, NULL, COALESCE(c.analytics_other, 0)) AS analytics_other,
  IF(a.table_name IS NULL, NULL, COALESCE(c.ads_yes, 0)) AS ads_yes,
  IF(a.table_name IS NULL, NULL, COALESCE(c.ads_no, 0)) AS ads_no,
  IF(a.table_name IS NULL, NULL, COALESCE(c.ads_unset, 0)) AS ads_unset,
  IF(a.table_name IS NULL, NULL, COALESCE(c.ads_other, 0)) AS ads_other
FROM days AS d
LEFT JOIN available AS a
  ON a.table_name = CONCAT('events_', FORMAT_DATE('%Y%m%d', d.day))
LEFT JOIN counts AS c USING (day)
ORDER BY day;

table_present = false kennzeichnet eine fehlende tägliche Basistabelle. Die Zählwerte bleiben dann NULL. Eine vorhandene leere Tabelle ergibt Null Ereignisse. Weder eine vorhandene Tabelle noch ein Nullwert belegen eine vollständige Erfassung. Die Abfrage setzt mindestens eine passende Exporttabelle und kompatible Schemas voraus. Zugriffs- und Schemafehler bleiben Fehler und werden nicht durch scheinbare Nullwerte verdeckt.

Der numerische Suffixfilter begrenzt die ausgewählten Tagestabellen. Vor der zeitgesteuerten Ausführung dienen ein BigQuery-Dryrun und ein Limit für abrechenbare Bytes zur Kostenkontrolle. Tagestabellen können bis zu drei Tage nach dem Ereignisdatum verspätete Ereignisse erhalten; aktuelle Ergebnisse bleiben vorläufig. Eine geplante Ergebnistabelle braucht einen Austausch oder ein Upsert der betroffenen Tage. Tägliches Anhängen des gesamten 30-Tage-Ergebnisses vervielfacht die Zählwerte. Eine kleine Berichtstabelle reduziert wiederholte Rohdatenabfragen, garantiert aber keinen festen Rechnungsbetrag.

3. Dashboard ohne irreführenden Trichter

Looker Studio unterstützt native Trichterdiagramme. Für die Folge „alle Ereignisse → Analytics Yes → Ads Yes“ passt diese Darstellung trotzdem nicht: Die beiden letzten Mengen müssen keine Teilmengen voneinander sein. Getrennte Balken oder Zeitreihen zeigen beide Speicherkategorien ohne erfundene Abfolge.

Die Berichtstabelle wird über den BigQuery-Connector verbunden. day dient als Datumsdimension; Zählfelder erhalten die Aggregation Summe. Zwei Kennzahlenkarten berechnen die Ereignisanteile aus den Summen:

CASE WHEN SUM(total_events) > 0 THEN SUM(analytics_yes) / SUM(total_events) ELSE NULL END

Die Felder erhalten das Prozentformat, ohne zusätzliche Multiplikation mit 100. Die entsprechende Ads-Formel verwendet ads_yes. Bei einem Nenner von null bleibt der Wert leer. Eine tägliche Zeitreihe verwendet dieselbe Berechnung mit Gruppierung nach day. Eine zusätzliche Tabelle zeigt Yes, No, Unset und Other je Speicherkategorie, die Ereigniszahl und table_present. Fehlende Tage bleiben als Lücken erkennbar.

Zeitraumvergleiche verwenden gleich lange Fenster und weisen fehlende Tage neben dem Ergebnis aus. Ein Mittelwert der Tagesprozente gewichtet kleine und große Tage gleich: 1 von 1 Ereignissen und 0 von 99 Ereignissen ergäben im Mittel 50 Prozent. Der korrekte gemeinsame Ereignisanteil beträgt dagegen 1 Prozent. Fehlende Tabellen dürfen nicht unbemerkt aus einem Zeitraumvergleich verschwinden.

4. Interpretation und Grenzen

Veränderungen können auf den Ereignismix, Zugriffsquellen, Standardwerte, Bannerkonfiguration, Tag-Reihenfolge oder Exportprobleme zurückgehen. Kontrollierte Prüfungen des Banners und der Tag-Anfragen, ergänzt um Änderungshistorie und Exportkontrolle, helfen bei der Eingrenzung. Ein gleichzeitiger Rückgang von Ereignisanteil und Gesamtvolumen belegt keine Ursache.

Der Bericht zeigt nicht, ob die GA4-Verhaltensmodellierung verfügbar oder aktiv ist. Googles Kriterien berücksichtigen absolute Ereignis- und Nutzerzahlen über mehrere Tage, die Implementierung sowie weitere Anforderungen an die Modellqualität. Ein Ereignisprozentsatz prüft diese Voraussetzungen nicht. Verhaltensmodellierung und Conversion-Modellierung beantworten zudem unterschiedliche Fragen.

Das Ergebnis enthält Tagesaggregate ohne Nutzerkennungen. Zugriffsbeschränkungen und ein sorgfältiger Umgang mit kleinen Gruppen bleiben erforderlich; Aggregation garantiert keine automatische Anonymität. Eine entscheidungsbezogene Zustimmungsquote benötigt eine separat definierte CMP-Kennzahl, einschließlich des Umgangs mit wiederholten Abfragen, geänderten Entscheidungen und unbeantworteten Bannern.

Fragen und Antworten

Belegt ein Anteil nahe 100 Prozent einen erfolgreichen Banner?

Nein. Wenn nur zugestimmter Verkehr GA4 erreicht, können fast alle erfassten Ereignisse den Status Yes tragen, während zahlreiche abgelehnte Besuche fehlen. Der Bericht beschreibt verfügbare Ereignisdaten statt sämtlicher Bannerinteraktionen.

Gehört Unset in die Kategorie No?

Nein. Getrennte Kategorien für Unset sowie fehlende oder unerwartete Werte machen Konfigurationslücken sichtbar. Der angezeigte Yes-Anteil verwendet weiterhin alle erfassten Ereignisse als Nenner.

Bedeutet ein fehlender Tag, dass keine Ereignisse auftraten?

Nein. Eine fehlende Exporttabelle ist ein Problem der Datenverfügbarkeit. Die Abfrage liefert dafür Nullwerte im Sinne von NULL; die Ereigniszahl 0 bleibt einer vorhandenen leeren Tabelle vorbehalten.

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Kontakt

Eine Frage oder eine Idee für ein Webprojekt? Schreib mir kurz, worum es geht. Das Formular nutzt reCAPTCHA zum Schutz vor Spam.

Kommentar schreiben

Erfahrungen aus der Praxis und Rückfragen zur Umsetzung sind hier willkommen.

Die E-Mail-Adresse wird nicht veröffentlicht. Pflichtfelder sind mit einem Stern versehen.