우리 포럼은 크지 않고, 대부분의 좋아요 반응은 “스태프”(관리자, 모더레이터, TL=4)에서 옵니다. 일반 사용자와 "스태프"의 좋아요를 비교해 보고, 일일 게시물 수를 나열하여 어떤 일이 일어나고 있는지, 그리고 반응 사용 개선을 위해 어디에 노력을 집중해야 하는지 파악하고 싶었습니다.
나와 내 친구 ChatGPT가 이것을 만들었습니다:
-- [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
@SaraDev의 원래 쿼리에 대한 변경 사항 (고맙습니다, Sara!):
SQL 변경 사항 요약
- 스태프 그룹 생성:
users테이블에서 스태프 사용자를 식별하기 위해staff_usersCTE를 추가했습니다. 스태프 사용자는 다음 중 하나에 해당하면 됩니다:
admin = truemoderator = truetrust_level = 4
- 스태프 좋아요 분리:
staff_users그룹의user_id로post_actions를 필터링하여 스태프 사용자의 좋아요 수(staff_likes_count)를 계산하는 서브쿼리를 추가했습니다. - 비(非)스태프 좋아요 컬럼 이름 변경:
비(非)스태프 좋아요의 출력 라벨을likes_count에서regular_likes_count로 변경했습니다. - 총 좋아요 추가:
regular_likes_count와staff_likes_count를 합산하는total_likes컬럼을 도입했습니다. - 일일 게시물 수 추가:
일일 게시물 수(posts_per_day)를 계산하는 서브쿼리를 추가하고 날짜 범위에 조인했습니다.
(네, ChatGPT가 이 변경 사항 목록도 저를 위해 만들어 주었습니다.)
결과 예시:
| 날짜 | regular_likes_count | staff_likes_count | posts_per_day |
|---|---|---|---|
| 1/1/24 | 0 | 6 | 7 |
| 1/2/24 | 0 | 5 | 3 |
| 1/3/24 | 1 | 0 | 4 |
| 1/4/24 | 1 | 2 | 5 |
| 1/5/24 | 9 | 9 | 30 |
| 1/6/24 | 0 | 1 | 11 |
| 1/7/24 | 2 | 4 | 11 |
| 1/8/24 | 0 | 5 | 18 |
| 1/9/24 | 0 | 0 | 2 |
| 1/10/24 | 0 | 0 | 7 |
| 1/11/24 | 0 | 4 | 5 |
| 1/12/24 | 4 | 0 | 4 |
| 1/13/24 | 6 | 0 | 10 |
| 1/14/24 | 1 | 7 | 18 |
| 1/15/24 | 2 | 4 | 7 |
주 단위로 보고하여 부드럽게 하기 위해 동일한 쿼리
-- [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
관심있을 경우를 위해, Sara의 쿼리를 수정한 최종 프롬프트는 다음과 같습니다:
두 날짜 사이의 일일 좋아요 수(likes_count)를 보고하는 SQL 쿼리가 있습니다. 주 단위로 데이터를 집계하고 추가 세부 정보를 포함하는 최종 출력을 생성하기 위해 다음과 같은 강화가 필요합니다:
- 스태프 그룹 정의:
users테이블에서staff_users그룹을 생성합니다. 사용자가 다음 기준 중 하나를 충족하면 스태프로 간주해야 합니다:admin = truemoderator = truetrust_level = 4
- 스태프/비(非)스태프별 좋아요 분리:
- 두 개의 별도 컬럼을 추가합니다:
regular_likes_count: 비(非)스태프 사용자의 좋아요 수.staff_likes_count: 스태프 사용자의 좋아요 수.
regular_likes_count컬럼이 스태프 사용자가 생성한 좋아요를 제외하도록 보장합니다.
- 총 좋아요 추가:
regular_likes_count와staff_likes_count를 합산하는total_likes컬럼을 포함합니다.
- 기간별 게시물 수 추가:
- 각 주 동안 생성된 게시물 수를 세는
posts_per_week컬럼을 추가합니다.
- 주 단위 집계:
- 쿼리를 수정하여 모든 데이터를 일 단위 대신 주 간격으로 그룹화합니다.
- 각 주의 시작 날짜를 나타내는
week_start컬럼을 포함합니다.
- 주 단위 제한:
- 결과를 지난 N주로 제한하기 위해
:weeks_ago매개변수를 도입합니다. 기본값은 52주(1년)여야 합니다.
- 정렬 및 최종 컬럼:
- 출력이
week_start기준으로 정렬되고 다음 컬럼이 이 순서로 포함되도록 보장합니다:week_start: 주의 시작 날짜.regular_likes_count: 비(非)스태프 사용자의 좋아요 수.staff_likes_count: 스태프 사용자의 좋아요 수.total_likes:regular_likes_count와staff_likes_count의 합.posts_per_week: 주 동안 생성된 게시물 수.