Dashboard-Bericht - Likes

Dies ist eine SQL-Version des Dashboard-Berichts für Likes.

Diese Abfrage liefert einen Bericht über die Gesamtzahl der Likes, die allen Beiträgen auf einer Website täglich innerhalb eines bestimmten Zeitraums gegeben wurden.

-- [params]
-- date :start_date = 2023-12-08
-- date :end_date = 2024-01-10

WITH date_range AS (
  SELECT date_trunc('day', series) AS date
  FROM generate_series(
    :start_date::timestamp,
    :end_date::timestamp,
    '1 day'::interval
  ) series
)

SELECT
  dr.date::date,
  COALESCE(pa.likes_count, 0) AS likes_count
FROM
  date_range dr
LEFT JOIN (
  SELECT
    date_trunc('day', pa.created_at) AS action_date,
    COUNT(*) AS likes_count
  FROM post_actions pa
  WHERE pa.post_action_type_id = 2
    AND pa.created_at >= :start_date
    AND pa.created_at <= (:end_date::date + 1)
  GROUP BY action_date
) pa ON dr.date = pa.action_date
ORDER BY dr.date

SQL-Abfrageerklärung

Die Hauptstruktur der Abfrage basiert auf einem CTE (Common Table Expression) namens date_range, der verwendet wird, um eine Reihe von Zeitstempeln zu generieren, von denen jeder einen anderen Tag innerhalb des vom Benutzer definierten Zeitraums darstellt.

Parameter

Die Abfrage akzeptiert zwei Parameter:

  • :start_date: Der Beginn des Zeitraums, für den der Bericht generiert werden soll.
  • :end_date: Das Ende des Zeitraums, für den der Bericht generiert werden soll.

Common Table Expression: date_range

  • generate_series ist eine Funktion, die eine Reihe von Zeitstempeln von :start_date bis :end_date erstellt, inkrementiert um ein Intervall von ‘1 Tag’.
  • date_trunc('day', series) kürzt den Zeitstempel auf den Beginn des Tages, wodurch alle Zeitstempel effektiv auf 00:00:00 ihrer jeweiligen Tage normalisiert werden.
  • Das Ergebnis ist eine Reihe von Daten, eine pro Zeile, die den gesamten Bereich von :start_date bis :end_date abdecken.

Unterabfrage: Zählen von Likes

Eine Unterabfrage wird verwendet, um die Anzahl der Likes für jeden Tag zu berechnen, indem Zeilen aus der Tabelle post_actions gezählt werden.

  • Diese Abfrage filtert post_actions nach Einträgen, bei denen der Aktionstyp ein Like angibt (wobei post_action_type_id = 2 ‘like’ bedeutet).
  • Sie filtert die Aktionen nach dem Datumsbereich und fügt dem Enddatum einen Tag hinzu, um Likes einzuschließen, die am letzten Tag gegeben wurden.
  • Sie gruppiert die Ergebnisse nach Tag und zählt die Likes für jeden Tag.

Hauptabfrage: Zusammenführen von Ergebnissen

Der letzte Abschnitt der Abfrage führt die Menge aller Daten aus dem date_range CTE mit der Anzahl der Likes aus der Unterabfrage zusammen.

  • Ein LEFT JOIN stellt sicher, dass alle Daten aus date_range im Ergebnis enthalten sind, auch wenn für ein bestimmtes Datum keine entsprechenden Like-Aktionen vorhanden sind (keine Joins in der Unterabfrage gefunden).
  • COALESCE wird verwendet, um NULL-Zählungen (von Tagen ohne Likes) durch Null zu ersetzen und sicherzustellen, dass der Bericht die Tage ohne jegliche Like-Aktivität genau widerspiegelt.
  • Der endgültige Ergebnissatz wird nach Datum sortiert, um eine chronologische Ansicht der über den angegebenen Zeitraum gegebenen Likes zu erhalten.

Beispielergebnisse

date likes_count
2023-12-08 123
2023-12-09 156
2023-12-10 278
2023-12-11 134
2023-12-12 89
2 „Gefällt mir“

Benötigt dieser eine AND pa.deleted_at IS NULL, um die Likes herauszufiltern, die dann entfernt werden, um sie abzugleichen, oder wäre das eine mögliche Änderung an der Dashboard-Abfrage selbst?

2 „Gefällt mir“

Wie es derzeit ist, enthält der Dashboard-Bericht gelöschte Likes. Das Hinzufügen von AND pa.deleted IS NULL würde daher die Übereinstimmung dieser Abfrage mit dem Dashboard-Bericht ändern.

Die Änderung des zugrunde liegenden Dashboard-Berichts, um gelöschte Likes nicht einzuschließen, könnte jedoch eine gute Änderung sein, die man in Betracht ziehen sollte.

2 „Gefällt mir“

Mein Forum ist nicht sehr groß, und die meisten unserer Reaktionen stammen von „Mitarbeitern“ (Admins, Moderatoren, TL=4). Ich wollte sehen, wie sich die Likes von normalen Benutzern im Vergleich zu „Mitarbeitern“ verhalten, und die Anzahl der Beiträge pro Tag auflisten, um besser zu verstehen, was vor sich geht und wo wir unsere Bemühungen konzentrieren müssen, um die Nutzung von Reaktionen zu verbessern.

Mein Kumpel ChatGPT und ich haben uns das ausgedacht:

-- [params]
-- date :start_date = 2024-01-01
-- date :end_date = 2024-12-31

WITH date_range AS (
  SELECT date_trunc('day', series) AS date
  FROM generate_series(
    :start_date::timestamp,
    :end_date::timestamp,
    '1 day'::interval
  ) series
),
staff_users AS (
  SELECT id
  FROM users
  WHERE admin = true OR moderator = true OR trust_level = 4
)

SELECT
  dr.date::date,
  COALESCE(pa_non_staff.regular_likes_count, 0) AS regular_likes_count,
  COALESCE(pa_staff.staff_likes_count, 0) AS staff_likes_count,
  COALESCE(pa_non_staff.regular_likes_count, 0) + COALESCE(pa_staff.staff_likes_count, 0) AS total_likes,
  COALESCE(posts_count.posts_per_day, 0) AS posts_per_day
FROM
  date_range dr
LEFT JOIN (
  SELECT
    date_trunc('day', pa.created_at) AS action_date,
    COUNT(*) AS regular_likes_count
  FROM post_actions pa
  WHERE pa.post_action_type_id = 2
    AND pa.user_id NOT IN (SELECT id FROM staff_users)
    AND pa.created_at >= :start_date
    AND pa.created_at <= (:end_date::date + 1)
  GROUP BY action_date
) pa_non_staff ON dr.date = pa_non_staff.action_date
LEFT JOIN (
  SELECT
    date_trunc('day', pa.created_at) AS action_date,
    COUNT(*) AS staff_likes_count
  FROM post_actions pa
  WHERE pa.post_action_type_id = 2
    AND pa.user_id IN (SELECT id FROM staff_users)
    AND pa.created_at >= :start_date
    AND pa.created_at <= (:end_date::date + 1)
  GROUP BY action_date
) pa_staff ON dr.date = pa_staff.action_date
LEFT JOIN (
  SELECT
    date_trunc('day', p.created_at) AS post_date,
    COUNT(*) AS posts_per_day
  FROM posts p
  WHERE p.created_at >= :start_date
    AND p.created_at <= (:end_date::date + 1)
  GROUP BY post_date
) posts_count ON dr.date = posts_count.post_date
ORDER BY dr.date

Änderungen an @SaraDevs ursprünglicher Abfrage (danke, Sara!):
Zusammenfassung der SQL-Änderungen

  1. Mitarbeitergruppe generieren:
    Eine staff_users-CTE wurde hinzugefügt, um Mitarbeiterbenutzer aus der users-Tabelle zu identifizieren. Ein Mitarbeiterbenutzer wird als einer der folgenden definiert:
    • admin = true
    • moderator = true
    • trust_level = 4
  2. Mitarbeiter-Likes separat erfassen:
    Eine Unterabfrage wurde hinzugefügt, um die Anzahl der Likes von Mitarbeitern (staff_likes_count) zu berechnen, indem post_actions nach user_id in der staff_users-Gruppe gefiltert wird.
  3. Spalte für Nicht-Mitarbeiter-Likes umbenennen:
    Die Ausgabekennzeichnung für Nicht-Mitarbeiter-Likes wurde von likes_count in regular_likes_count geändert.
  4. Gesamt-Likes hinzufügen:
    Eine Spalte total_likes wurde eingeführt, um regular_likes_count und staff_likes_count zu summieren.
  5. Beiträge pro Tag hinzufügen:
    Eine Unterabfrage wurde hinzugefügt, um die Anzahl der Beiträge pro Tag (posts_per_day) zu berechnen und sie mit dem Datumsbereich zu verknüpfen.
    (Ja, ChatGPT hat diese Liste der Änderungen auch für mich erstellt.)

Beispielergebnisse:

Datum regular_likes_count staff_likes_count posts_per_day
01.01.24 0 6 7
02.01.24 0 5 3
03.01.24 1 0 4
04.01.24 1 2 5
05.01.24 9 9 30
06.01.24 0 1 11
07.01.24 2 4 11
08.01.24 0 5 18
09.01.24 0 0 2
10.01.24 0 0 7
11.01.24 0 4 5
12.01.24 4 0 4
13.01.24 6 0 10
14.01.24 1 7 18
15.01.24 2 4 7
Gleiche Abfrage wochenweise gemeldet zur Glättung
-- [params]
-- integer :weeks_ago = 52

WITH date_range AS (
  SELECT date_trunc('week', series) AS week_start
  FROM generate_series(
    date_trunc('week', now()) - (:weeks_ago || ' weeks')::interval,
    date_trunc('week', now()),
    '1 week'::interval
  ) series
),
staff_users AS (
  SELECT id
  FROM users
  WHERE admin = true OR moderator = true OR trust_level = 4
)

SELECT
  dr.week_start::date AS week_start,
  COALESCE(pa_non_staff.regular_likes_count, 0) AS regular_likes_count,
  COALESCE(pa_staff.staff_likes_count, 0) AS staff_likes_count,
  COALESCE(pa_non_staff.regular_likes_count, 0) + COALESCE(pa_staff.staff_likes_count, 0) AS total_likes,
  COALESCE(posts_count.posts_per_week, 0) AS posts_per_week
FROM
  date_range dr
LEFT JOIN (
  SELECT
    date_trunc('week', pa.created_at) AS action_week,
    COUNT(*) AS regular_likes_count
  FROM post_actions pa
  WHERE pa.post_action_type_id = 2
    AND pa.user_id NOT IN (SELECT id FROM staff_users)
    AND pa.created_at >= date_trunc('week', now()) - (:weeks_ago || ' weeks')::interval
    AND pa.created_at <= date_trunc('week', now())
  GROUP BY action_week
) pa_non_staff ON dr.week_start = pa_non_staff.action_week
LEFT JOIN (
  SELECT
    date_trunc('week', pa.created_at) AS action_week,
    COUNT(*) AS staff_likes_count
  FROM post_actions pa
  WHERE pa.post_action_type_id = 2
    AND pa.user_id IN (SELECT id FROM staff_users)
    AND pa.created_at >= date_trunc('week', now()) - (:weeks_ago || ' weeks')::interval
    AND pa.created_at <= date_trunc('week', now())
  GROUP BY action_week
) pa_staff ON dr.week_start = pa_staff.action_week
LEFT JOIN (
  SELECT
    date_trunc('week', p.created_at) AS post_week,
    COUNT(*) AS posts_per_week
  FROM posts p
  WHERE p.created_at >= date_trunc('week', now()) - (:weeks_ago || ' weeks')::interval
    AND p.created_at <= date_trunc('week', now())
  GROUP BY post_week
) posts_count ON dr.week_start = posts_count.post_week
ORDER BY dr.week_start

Falls es interessant ist, hier sind die endgültigen Prompts, die Saras Abfrage modifiziert haben:

Ich habe eine SQL-Abfrage, die die tägliche Anzahl von Likes (likes_count) zwischen zwei Daten meldet, aber ich muss die folgenden Verbesserungen vornehmen, um eine endgültige Ausgabe zu erstellen, die Daten nach Wochen aggregiert und zusätzliche Details enthält:

  1. Definieren einer Mitarbeitergruppe:
    • Erstellen Sie eine staff_users-Gruppe aus der users-Tabelle. Ein Benutzer sollte als Mitarbeiter betrachtet werden, wenn er eine der folgenden Kriterien erfüllt:
      • admin = true
      • moderator = true
      • trust_level = 4
  2. Likes nach Mitarbeitern und Nicht-Mitarbeitern trennen:
    • Fügen Sie zwei separate Spalten hinzu:
      • regular_likes_count: Anzahl der Likes von Nicht-Mitarbeitern.
      • staff_likes_count: Anzahl der Likes von Mitarbeitern.
    • Stellen Sie sicher, dass die Spalte regular_likes_count Likes von Mitarbeitern ausschließt.
  3. Gesamt-Likes hinzufügen:
    • Fügen Sie eine Spalte total_likes hinzu, die regular_likes_count und staff_likes_count summiert.
  4. Beiträge pro Zeitraum hinzufügen:
    • Fügen Sie eine Spalte posts_per_week hinzu, die die Anzahl der Beiträge zählt, die während jeder Woche erstellt wurden.
  5. Nach Wochen aggregieren:
    • Ändern Sie die Abfrage so, dass alle Daten nach wöchentlichen Intervallen anstatt täglich gruppiert werden.
    • Fügen Sie eine Spalte week_start hinzu, die das Startdatum jeder Woche darstellt.
  6. Nach Wochen begrenzen:
    • Führen Sie einen Parameter :weeks_ago ein, um die Ergebnisse auf die letzten N Wochen zu beschränken. Der Standardwert sollte 52 Wochen (1 Jahr) sein.
  7. Sortieren und endgültige Spalten:
    • Stellen Sie sicher, dass die Ausgabe nach week_start sortiert ist und die folgenden Spalten in dieser Reihenfolge enthält:
      1. week_start: Das Startdatum der Woche.
      2. regular_likes_count: Die Anzahl der Likes von Nicht-Mitarbeitern.
      3. staff_likes_count: Die Anzahl der Likes von Mitarbeitern.
      4. total_likes: Die Summe von regular_likes_count und staff_likes_count.
      5. posts_per_week: Die Anzahl der Beiträge, die während der Woche erstellt wurden.
2 „Gefällt mir“