متطلب تقرير نشاط المستخدم المعقد

شكرًا جزيلاً لك على ذلك!

حقل ملف تعريف المستخدم المخصص الذي أحاول استخدامه هو ‘رقم NZRAB’

لقد جربت الأمر مع السكربت الناتج أدناه، لكنني ارتكبت خطأً بوضوح، حيث ظهر لي خطأ ‘دالة غير معرفة’

لم أكن متأكدًا مما إذا كان يجب استبعاد الأحرف الكبيرة أو المسافات من اسم الحقل - على الأقل لم يبدو أن المحرر يحب المسافة في اسم الحقل، لذا استبدلتها بعلامة سفلية

قد أكون أيضًا أخلط بين اسم الحقل وتسمية الحقل - لكن إذا كان الأمر كذلك، فأنا لا أعرف كيفية معرفة اسم الحقل الذي ينتمي إلى التسمية ‘رقم NZRAB’

-- coverage: 'week', 'all', or 'date'
-- [params]
-- date :start_date = 2019-08-27
-- date :end_date = 2019-09-30
-- text :coverage = week

WITH date_range AS (
SELECT date_trunc('day', dd):: date AS "date", EXTRACT(week from date_trunc('day', dd):: date) AS "week"
FROM generate_series
        ( :start_date::timestamp 
        , :end_date::timestamp
        , '1 day'::interval) dd
), likes_given AS (
SELECT u.id, dr.date, dr.week, count(pa.*) AS "likes"
FROM date_range dr
FULL JOIN users u ON (1=1)
LEFT JOIN post_actions pa ON (pa.created_at:: date = dr.date and post_action_type_id=2 AND user_id = u.id)
GROUP BY dr.date, dr.week, u.id
ORDER BY u.id, dr.date
), posts_summary AS (
SELECT u.id, u.username, u.created_at, dr.*, count(p.id) - count(t.id) AS replies, count(t.id) AS topics, COALESCE(sum(p.like_count),0) AS likes_received, cf.value as NZRAB_number
from date_range dr
FULL OUTER JOIN users u ON (1=1)
LEFT JOIN posts p ON (p.user_id = u.id AND p.created_at::date=dr.date AND p.deleted_at IS NULL)
LEFT JOIN topics t ON (t.user_id = u.id AND t.created_at::date = dr.date AND p.topic_id = t.id AND t.deleted_at IS NULL)
LEFT JOIN user_custom_fields cf ON (u.id = cf.user_id and cf.name = 'NZRAB number') 
GROUP BY u.id, dr.date, dr.week
ORDER BY u.id, dr.date
)
SELECT ps.id, ps.username, ps.created_at, ps.NZRAB_number, CASE
WHEN :coverage::text = 'week' THEN ps.week::text
WHEN :coverage::text = 'all' THEN '-1'
ELSE ps.date::text
END  AS period, sum(ps.replies) AS replies, sum(ps.topics) AS topics, sum(ps.likes_received) AS likes_received, sum(lg.likes) AS likes_given, COALESCE(sum(posts_read),0) AS posts_read, COALESCE(sum(time_read),0) AS time_read, SUM(visits) AS visits
FROM posts_summary ps

LEFT JOIN likes_given lg ON (ps.date = lg.date AND ps.id = lg.id)
LEFT JOIN visits v ON (v.id = ps.id AND v.date = ps.date)
GROUP BY ps.id, ps.username, ps.created_at, CASE 
WHEN :coverage::text = 'week' THEN ps.week::text
WHEN :coverage::text = 'all' THEN '-1'
ELSE ps.date::text
END  
ORDER BY ps.id, CASE
WHEN :coverage::text = 'week' THEN ps.week::text
WHEN :coverage::text = 'all' THEN '-1'
ELSE ps.date::text
END

الخطأ الناتج:

PG::UndefinedFunction: ERROR: operator does not exist: integer == integer
LINE 32: LEFT JOIN user_custom_fields cf ON (u.id == cf.user_id and c…
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.

إذا خلصت من هذا إلى أنني لا أعرف ما أفعل، فستكون محقًا!

تمكنت من الحصول على مثال يعمل من الكود الخاص بك.

-- coverage: 'week'، 'all'، أو 'date'
-- [params]
-- date :start_date = 2019-08-27
-- date :end_date = 2019-09-30
-- text :coverage = week

WITH date_range AS (
SELECT date_trunc('day', dd):: date AS "date", EXTRACT(week from date_trunc('day', dd):: date) AS "week"
FROM generate_series
        ( :start_date::timestamp 
        , :end_date::timestamp
        , '1 day'::interval) dd
), likes_given AS (
SELECT u.id, dr.date, dr.week, count(pa.*) AS "likes"
FROM date_range dr
FULL JOIN users u ON (1=1)
LEFT JOIN post_actions pa ON (pa.created_at:: date = dr.date and post_action_type_id=2 AND user_id = u.id)
GROUP BY dr.date, dr.week, u.id
ORDER BY u.id, dr.date
), posts_summary AS (
SELECT u.id, u.username, u.created_at, dr.*, count(p.id) - count(t.id) AS replies, count(t.id) AS topics, COALESCE(sum(p.like_count),0) AS likes_received, cf.value as nzrab_number
from date_range dr
FULL OUTER JOIN users u ON (1=1)
LEFT JOIN posts p ON (p.user_id = u.id AND p.created_at::date=dr.date AND p.deleted_at IS NULL)
LEFT JOIN topics t ON (t.user_id = u.id AND t.created_at::date = dr.date AND p.topic_id = t.id AND t.deleted_at IS NULL)
LEFT JOIN user_custom_fields cf ON (u.id = cf.user_id and cf.name = CONCAT('user_field_', (select id::text from user_fields where name='NZRAB number'))) 
GROUP BY u.id, dr.date, dr.week, cf.value
ORDER BY u.id, dr.date
)

SELECT ps.id, ps.username, ps.created_at, ps.NZRAB_number, CASE
WHEN :coverage::text = 'week' THEN ps.week::text
WHEN :coverage::text = 'all' THEN '-1'
ELSE ps.date::text
END  AS period, sum(ps.replies) AS replies, sum(ps.topics) AS topics, sum(ps.likes_received) AS likes_received, sum(lg.likes) AS likes_given
FROM posts_summary ps
LEFT JOIN likes_given lg ON (ps.date = lg.date AND ps.id = lg.id)
GROUP BY ps.id, ps.username, ps.created_at, ps.nzrab_number, CASE 
WHEN :coverage::text = 'week' THEN ps.week::text
WHEN :coverage::text = 'all' THEN '-1'
ELSE ps.date::text
END  
ORDER BY ps.id, CASE
WHEN :coverage::text = 'week' THEN ps.week::text
WHEN :coverage::text = 'all' THEN '-1'
ELSE ps.date::text
END

ملاحظة: العلاقة في user_custom_fields غريبة بعض الشيء. إذا لم يعمل، قد تحتاج إلى تشغيل استعلام منفصل لتحديد الاسم الصحيح للاستخدام:

في استعلام منفصل، قم بتشغيل:

select * from user_custom_fields

ابحث عن سجل في مجموعة النتائج يتطابق مع حقل “NZRAB number” الخاص بك، وابحث عن الاسم. بالنسبة لي كان “user_field_2”.

بمجرد الحصول على ذلك، استبدل هذا السطر في الاستعلام أعلاه:

LEFT JOIN user_custom_fields cf ON (u.id = cf.user_id and cf.name = CONCAT('user_field_', (select id::text from user_fields where name='NZRAB number'))) 

بـ

LEFT JOIN user_custom_fields cf ON (u.id = cf.user_id and cf.name = <YOUR FIELD NAME>)

آمل ألا تحتاج إلى القيام بذلك.

رائع - لقد نجح ذلك معي تمامًا كما هو!

لأجرب حظي أكثر، هل من الممكن تقنيًا إحصاء المنشورات التي حصلت على إعجابات بشكل منفصل عن تلك التي لم تحصل على إعجابات؟

السبب في سؤالي هو أنه لا توجد طريقة أخرى لمعرفة ما إذا كان شخص حصل على 8 إعجابات قد حصل عليها جميعًا لمنشور واحد، أم أنها موزعة على عدة منشورات.

والسؤال الآخر هو: هل توجد طريقة لتقييد المخرجات لتشمل فقط الأشخاص الذين يحتوي حقل NZRAB_number المخصص لديهم على أرقام بين رقمين يتم تزويدهما من قبل المستخدم؟ (استبعاد الأشخاص الذين سجلوا دخولهم وأدخلوا نصًا، أو لم يدخلوا شيئًا على الإطلاق في هذا الحقل)

وكذلك عرض الاسم الحقيقي للمستخدم بجانب معرف المستخدم؟