إسناد اختبارات A/B ومقاييسها
ربط إسناد التجربة بالنتائج وحساب المقاييس لكل متغير
إسناد اختبارات A/B ومقاييسها درس مجاني في SQL Interview Prep على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.
ما الذي يختبره سؤال اختبار A/B
تتحقق أسئلة اختبار A/B من قدرتك على ربط تعيين التجربة بالنتائج بشكل صحيح وحساب مقياس واضح لكل متغير.
يكمن الفخ غالبًا في الربط: احتساب نتائج لمستخدمين لم يُسجَّلوا في التجربة قط، أو احتساب المستخدمين المعيَّنين مرتين. إذا نفذت ربط التعيين بشكل صحيح، فسيصبح حساب المقاييس عملية حسابية سهلة.
الجدولان اللذان تحصل عليهما
توقّع وجود جدول التعيينات وجدول النتائج:
assignments(user_id, variant, assigned_at)حيث تكون قيمة المتغير 'control' أو 'treatment'.orders(user_id, order_id, amount, created_at)أو جدول أحداث عام.
التعيين هو مصدر الحقيقة لتحديد المستخدمين المشاركين في التجربة. ولا تُحتسب النتائج إلا إذا ظهر المستخدم في جدول التعيينات.
CREATE TABLE assignments (
user_id INT,
variant VARCHAR(20),
assigned_at TIMESTAMP
);
CREATE TABLE orders (
user_id INT,
order_id INT,
amount NUMERIC,
created_at TIMESTAMP
);ابدأ من جدول التعيينات ثم استخدم LEFT JOIN للنتائج
القاعدة الأساسية: ابدأ من جدول التعيينات ونفّذ LEFT JOIN مع النتائج. فهذا يحافظ على المستخدمين الذين سُجّلوا في التجربة لكنهم لم يجروا تحويلاً، وهو ما تحتاج إليه للحصول على مقام صادق.
أما INNER JOIN فسيسقط بصمت المستخدمين الذين لم يجروا تحويلاً، مما يؤدي إلى تضخيم معدل التحويل.
SELECT
a.user_id,
a.variant,
o.order_id
FROM assignments a
LEFT JOIN orders o
ON o.user_id = a.user_id;حساب التحويل لكل متغير
معدل التحويل = المستخدمون الذين أجروا تحويلاً / المستخدمون المعيَّنون، لكل متغير. احسب عدد المستخدمين الذين أجروا تحويلاً بشكل مميز في البسط، وجميع المستخدمين المعيَّنين في المقام.
استخدم COUNT(DISTINCT ...) على مستخدم الطلب، حتى يُحتسب المستخدم الذي لديه ثلاثة طلبات كمستخدم واحد أجرى تحويلاً.
SELECT
a.variant,
COUNT(DISTINCT a.user_id) AS assigned,
COUNT(DISTINCT o.user_id) AS converters,
ROUND(100.0 * COUNT(DISTINCT o.user_id)
/ COUNT(DISTINCT a.user_id), 2) AS conv_rate_pct
FROM assignments a
LEFT JOIN orders o ON o.user_id = a.user_id
GROUP BY a.variant;فخ التعيين المزدوج
ماذا يحدث إذا ظهر المستخدم مرتين في جدول التعيينات، مرة في كل متغير؟ سيحتسب الربط المستخدم في كلا الجانبين، فتتلوث التجربة.
يضع المحاورون هذا الفخ عمدًا. احمِ استعلامك منه: أزل التكرارات من التعيينات بحيث يبقى متغير واحد لكل مستخدم، ويكون ذلك عادةً هو التعيين الأول، قبل تنفيذ الربط.
WITH dedup AS (
SELECT user_id, variant,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY assigned_at) AS rn
FROM assignments
)
SELECT user_id, variant
FROM dedup
WHERE rn = 1;احتسب النتائج بعد التعيين فقط
لا يمكن أن يكون الطلب الذي أُنشئ قبل تعيين المستخدم ناتجًا عن التجربة. أضف قيدًا زمنيًا: يجب أن تحدث النتيجة في وقت assigned_at أو بعده.
ضع هذا الشرط في عبارة ON ضمن LEFT JOIN، حتى يظل المستخدمون الذين لم يجروا تحويلاً محفوظين.
SELECT
a.variant,
COUNT(DISTINCT a.user_id) AS assigned,
COUNT(DISTINCT o.user_id) AS converters
FROM assignments a
LEFT JOIN orders o
ON o.user_id = a.user_id
AND o.created_at >= a.assigned_at
GROUP BY a.variant;ON مقابل WHERE في ربط النتائج
هذا سؤال متابعة مؤكد. إذا نقلت o.created_at >= a.assigned_at إلى WHERE، فستحوّل LEFT JOIN إلى ربط داخلي: إذ تكون قيمة o.created_at = NULL في الصفوف التي لم ينفذ فيها المستخدم أي طلب، ويكون الشرط UNKNOWN، فتختفي هذه الصفوف.
أبقِ شروط تصفية النتائج في ON للحفاظ على المستخدمين الذين لم يجروا تحويلاً في المقام.
مقاييس الإيرادات لكل متغير
بالإضافة إلى التحويل، قد يطلب المحاورون الإيراد لكل مستخدم (ARPU) والإيراد لكل مستخدم أجرى تحويلاً. اجمع المبلغ، ثم اقسمه على المقام الصحيح.
يُحسب ARPU بقسمة الإيراد على جميع المستخدمين المعيَّنين، بينما يُحسب الإيراد لكل مستخدم أجرى تحويلاً بالقسمة على المستخدمين الذين نفذوا طلبًا فقط. وضّح دائمًا أي مقياس يريده النشاط التجاري.
SELECT
a.variant,
COUNT(DISTINCT a.user_id) AS assigned,
COALESCE(SUM(o.amount), 0) AS revenue,
ROUND(COALESCE(SUM(o.amount), 0)
/ COUNT(DISTINCT a.user_id), 2) AS arpu
FROM assignments a
LEFT JOIN orders o
ON o.user_id = a.user_id
AND o.created_at >= a.assigned_at
GROUP BY a.variant;نمط التجميع على مستويين
عندما يكون المقياس هو "متوسط عدد الطلبات لكل مستخدم"، لا تحسبه في عملية واحدة، لأنك ستخلط بين مستوى المستخدم ومستوى الطلب. اجمع البيانات على مستوى المستخدم أولًا، ثم احسب المتوسط عبر المستخدمين.
هذا النمط، أي لكل مستخدم ثم لكل متغير، هو مستوى التجميع الصحيح، ويمثل معيارًا شائعًا للتمييز في المقابلات.
WITH per_user AS (
SELECT a.variant, a.user_id,
COUNT(o.order_id) AS orders_cnt
FROM assignments a
LEFT JOIN orders o
ON o.user_id = a.user_id
AND o.created_at >= a.assigned_at
GROUP BY a.variant, a.user_id
)
SELECT variant, ROUND(AVG(orders_cnt), 3) AS avg_orders_per_user
FROM per_user
GROUP BY variant;استعلام كامل وقابل للدفاع عنه
اجمع كل العناصر: أزل التكرارات بحيث يبقى التعيين الأول، وابدأ من جدول التعيينات، وطبّق القيد الزمني على النتائج في ON، ثم اعرض التحويل وARPU لكل متغير. اشرح كل قيد أثناء كتابته.
WITH enrolled AS (
SELECT user_id, variant, assigned_at
FROM (
SELECT user_id, variant, assigned_at,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY assigned_at) AS rn
FROM assignments
) x WHERE rn = 1
)
SELECT
e.variant,
COUNT(DISTINCT e.user_id) AS assigned,
COUNT(DISTINCT o.user_id) AS converters,
ROUND(100.0 * COUNT(DISTINCT o.user_id)
/ COUNT(DISTINCT e.user_id), 2) AS conv_pct,
ROUND(COALESCE(SUM(o.amount),0)
/ COUNT(DISTINCT e.user_id), 2) AS arpu
FROM enrolled e
LEFT JOIN orders o
ON o.user_id = e.user_id
AND o.created_at >= e.assigned_at
GROUP BY e.variant;فحوصات المعقولية التي يتوقعها المحاورون
قبل عرض النتائج، تحقّق من إعداد التجربة:
- هل أحجام المتغيرات متقاربة تقريبًا؟ إن كانت النسبة 90/10 بينما كان المقصود 50/50، فهذا يشير إلى وجود خطأ.
- هل ظهر أي مستخدم في كلا المتغيرين؟ احسب المستخدمين الذين لديهم أكثر من متغير مميز واحد.
- هل توجد تعيينات لا تملك نافذة نتائج ممكنة، مثل تعيين حدث بعد الحد الزمني الأخير للبيانات؟
إن عرض هذه الفحوصات دون أن يُطلب منك ذلك يدل على نضج تحليلي.
SELECT user_id, COUNT(DISTINCT variant) AS variant_count
FROM assignments
GROUP BY user_id
HAVING COUNT(DISTINCT variant) > 1;تحقق سريع
تحسب التحويل لكل متغير عبر تنفيذ LEFT JOIN للطلبات مع التعيينات، لكنك وضعت o.created_at >= a.assigned_at في عبارة WHERE. ماذا يحدث؟
مراجعة: تعيين اختبار A/B ومقاييسه
أصبح لديك الآن منهج عملي قابل للدفاع عنه لتحليل التجارب:
- اعتبر التعيين مصدر الحقيقة، ونفّذ LEFT JOIN مع النتائج.
- أزل التكرارات بحيث يبقى متغير واحد لكل مستخدم، أي التعيين الأول.
- طبّق القيد الزمني على النتائج في عبارة ON وليس WHERE، للحفاظ على المستخدمين الذين لم يجروا تحويلاً.
- اختر المقام الصحيح للتحويل وARPU والإيراد لكل مستخدم أجرى تحويلاً.
- اجمع البيانات على مستوى المستخدم أولًا عند حساب المتوسطات لكل مستخدم.
- نفّذ فحوصات المعقولية لتوازن التقسيم وظهور المستخدم في أكثر من تعيين.
التالي: تحويل هذه المقاييس لكل متغير إلى الرفع والدلالة الإحصائية ومقاييس الحماية.
الأسئلة الشائعة
هل درس «إسناد اختبارات A/B ومقاييسها» مجاني؟
نعم — نص درس «إسناد اختبارات A/B ومقاييسها» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.
ماذا ستتعلم في «إسناد اختبارات A/B ومقاييسها»؟
ربط إسناد التجربة بالنتائج وحساب المقاييس لكل متغير تتمرن على SQL Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ SQL Interview Prep؟
لا تُشترط خبرة سابقة. SQL Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «إسناد اختبارات A/B ومقاييسها»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس SQL Interview Prep هذا؟
نعم. كل درس في SQL Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- إنشاء مسار تحويل متعدد الخطوات
- الأحداث المرتبة والنوافذ الزمنية
- إسناد اختبارات A/B ومقاييسها
- التحسن والدلالة والضوابط في SQL