प्रांप्ट और लागू संदर्भ
आपको यह PostgreSQL तालिका दी गई है:
CREATE TABLE events (
user_id bigint NOT NULL,
event_id bigint PRIMARY KEY,
event_name text NOT NULL,
event_time timestamptz NOT NULL
);तीन चरणों वाले फ़नल की गणना करें: visit → signup → purchase। एक उपयोगकर्ता कोहोर्ट में प्रवेश करता है यदि उसके पास अर्ध-खुले रिपोर्टिंग अंतराल [start_at, end_at) में कम से कम एक visit है। उस अंतराल में उनका सबसे पहला visit फ़नल एंकर है। योग्य signup उस एंकर के बाद का सबसे पहला signup है; योग्य purchase चयनित signup के बाद का सबसे पहला purchase है। दोनों एंकर visit के 24 घंटे के भीतर ही होने चाहिए।
event_id अद्वितीय है। इवेंट निर्माता यह गारंटी देता है कि जब एक ही उपयोगकर्ता के लिए दो इवेंट एक ही टाइमस्टैम्प साझा करते हैं, तो छोटा event_id पहले हुआ था। एंकर के ठीक 24 घंटे बाद की purchase मान्य है; एक माइक्रोसेकंड बाद की भी मान्य नहीं है। फ़नल चरणों के बीच अन्य इवेंट की अनुमति है, और डुप्लिकेट चरण इवेंट के कारण किसी उपयोगकर्ता को दो बार नहीं गिना जाना चाहिए।
visited_users, signed_up_users, purchased_users, signup_rate, और purchase_rate के साथ एक पंक्ति लौटाएं। दोनों दरें visit कोहोर्ट से संचयी हैं, जिन्हें चार दशमलव स्थानों तक पूर्णांकित भिन्नों के रूप में व्यक्त किया गया है। एक खाली कोहोर्ट शून्य गणना और शून्य (null) दरें लौटाता है।
यह प्रश्न डेटा विश्लेषक, एनालिटिक्स इंजीनियर और उत्पाद एनालिटिक्स साक्षात्कारों के लिए उपयुक्त है। यह सशर्त एकत्रीकरण से कहीं अधिक का परीक्षण करता है: उम्मीदवार को कोहोर्ट ग्रेन को परिभाषित करना होगा, इवेंट क्रम को संरक्षित करना होगा, इवेंट दोहराए जाने पर एक मान्य श्रृंखला का चयन करना होगा, समय सीमाओं को संभालना होगा, और यह साबित करना होगा कि क्वेरी किसी असंभव यात्रा की गणना नहीं कर सकती है।
साक्षात्कारकर्ता क्या मूल्यांकन करता है
पहला संकेत मेट्रिक-अनुबंध अनुशासन है। "वे उपयोगकर्ता जिन्होंने तीनों इवेंट पूरे किए" पर्याप्त नहीं है। साक्षात्कारकर्ता यह जानना चाहता है कि कौन सा visit यात्रा को एंकर करता है, क्या चरणों का क्रमित होना आवश्यक है, क्या विंडो visit के 24 घंटे बाद बंद होती है या प्रत्येक चरण के बाद, और क्या दरें हरक पिछले चरण का उपयोग करती हैं या हर कोहोर्ट को हरक के रूप में। प्रत्येक विकल्प परिणाम बदल देता है।
दूसरा संकेत ग्रेन नियंत्रण है। रॉ तालिका प्रति इवेंट एक पंक्ति है, लेकिन आउटपुट उपयोगकर्ताओं की गणना करता है। कोहोर्ट में प्रति उपयोगकर्ता अधिकतम एक पंक्ति होनी चाहिए, और प्रत्येक बाद के लुकअप को उस कोहोर्ट पंक्ति के लिए अधिकतम एक इवेंट उत्पन्न करना चाहिए। एक व्यापक जॉइन के बाद COUNT(DISTINCT user_id) लगाने से एक मान्य इवेंट श्रृंखला स्थापित होने के बजाय एक गलत श्रृंखला छिप सकती है।
तीसरा संकेत अनुक्रमिक तर्क है। स्वतंत्र व्यंजक जैसे MIN(CASE WHEN event_name = 'purchase' ...) आवश्यक रूप से चयनित signup के बाद सबसे पहली purchase नहीं खोजते हैं। एक उपयोगकर्ता purchase कर सकता है, फिर signup कर सकता है, फिर से purchase कर सकता है। मान्य purchase दूसरी वाली है। इसलिए प्रत्येक चरण को पिछले चरण द्वारा चुने गए इवेंट की आवश्यकता होती है।
चौथा संकेत नियतात्मक लौकिक तर्क (deterministic temporal logic) है। अकेले टाइमस्टैम्प समान-समय वाले इवेंट को क्रमित नहीं करते हैं। यह प्रॉम्प्ट टाई-ब्रेकर के रूप में event_id प्रदान करता है, इसलिए तुलना कुंजी टपल (event_time, event_id) है। उस गारंटी के बिना, डेटा यह साबित नहीं कर सकता कि कौन सा समान-समय वाला इवेंट पहले आया था, और SQL को अपनी तरफ से कार्य-कारण संबंध नहीं बनाना चाहिए।
अंतिम संकेत परिचालन निर्णय है। एक फ़नल जिसकी विंडो end_at से आगे बढ़ती है, उसे बाद के इवेंट डेटा की आवश्यकता होती है। रिपोर्ट केवल तभी परिपक्व होती है जब पाइपलाइन ने end_at + 24 hours के माध्यम से प्रक्रिया पूरी कर ली हो। उम्मीदवार को केवल सिंटैक्टिक रूप से मान्य SQL पर रुकने के बजाय देर से आने वाले डेटा, इंडेक्स, क्वेरी प्लान और मेट्रिक परिभाषा का परीक्षण करने वाले फिक्स्चर पर चर्चा करनी चाहिए।
उत्तर देने से पहले स्पष्ट करने योग्य प्रश्न
- कौन सा इवेंट उपयोगकर्ता को एंकर करता है? यह उत्तर रिपोर्टिंग अंतराल के भीतर सबसे पहले visit का उपयोग करता है,
भले ही उपयोगकर्ता ने अंतराल से पहले visit किया हो। "अब तक का पहला visit" के लिए ऐतिहासिक डेटा और एक अलग कोहोर्ट फ़िल्टर की आवश्यकता होगी।
- क्या फ़नल क्रमित है? हाँ। एक signup एंकर visit के बाद होना चाहिए, और एक purchase चयनित
signup के बाद होनी चाहिए। अक्रमित इवेंट की उपस्थिति एक अलग मेट्रिक है।
- विंडो कहाँ से शुरू और समाप्त होती है? यह एंकर visit से शुरू होती है और
visit_time + 24 hoursपर समावेशी रूप से
बंद होती है। यह signup के बाद पुनरारंभ नहीं होती है।
- क्या बाद के चरण
end_atके बाहर हो सकते हैं? हाँ, बशर्ते वे उपयोगकर्ता की 24 घंटे की विंडो के भीतर हों।
end_at एंकर visit का चयन करता है; यह रूपांतरण के अवसरों को छोटा नहीं करता है।
- समान टाइमस्टैम्प कैसे क्रमित होते हैं? निर्माता की गारंटी का उपयोग करते हुए, पहले
event_timeऔर बाद मेंevent_idकी
तुलना करें। यदि कोई विश्वसनीय क्रम मौजूद नहीं है, तो समान-समय वाले चरण अस्पष्ट हैं।
- प्रत्येक दर को कौन सा भाजक (denominator) परिभाषित करता है? दोनों
visited_usersका उपयोग करते हैं। एक चरण-दर-चरण purchase दर
purchasers को signed-up उपयोगकर्ताओं से विभाजित करेगी और उसका एक अलग कॉलम नाम होना चाहिए।
- खाली इनपुट क्या लौटाता है? गणना शून्य होती है; दरें null होती हैं क्योंकि कोई सार्थक
भाजक नहीं होता है। NULLIF शून्य से विभाजन को रोकता है।
- रिपोर्ट कब अंतिम होती है? केवल तब जब डेटा-पूर्णता वॉटरमार्क प्रत्येक कोहोर्ट सदस्य के
पूरे 24 घंटे के अवसर को कवर करता है और देर से आने की नीति लागू कर दी गई हो।
30-सेकंड उत्तर रूपरेखा
"मैं पहले अर्ध-खुले रिपोर्टिंग अंतराल में visits को रैंक करके और रैंक एक को रखकर कोहोर्ट को प्रति उपयोगकर्ता एक पंक्ति बनाऊंगा। प्रत्येक एंकर के लिए, एक left lateral लुकअप सबसे शुरुआती signup ढूंढता है जिसका (event_time, event_id) visit के बाद है और जिसका समय 24 घंटे के भीतर है। दूसरा left lateral लुकअप purchase के लिए भी यही करता है, लेकिन मूल 24-घंटे की समय सीमा को बनाए रखते हुए चयनित signup के बाद शुरू होता है। यह प्रति visit किए गए उपयोगकर्ता के लिए एक प्रगति पंक्ति बनाता है। फिर मैं दो पूर्ण चरणों के लिए फ़िल्टर की गई गणनाओं का उपयोग कर सकता हूं और दोनों को visit गणना से विभाजित कर सकता हूं। मैं उल्टे इवेंट, डुप्लिकेट, समान टाइमस्टैम्प, सटीक 24-घंटे की सीमा, दोहराए गए visits, एक खाली कोहोर्ट और रिपोर्ट परिपक्वता का परीक्षण करूंगा।"
चरण-दर-चरण गहन विश्लेषण
कोहोर्ट सबसे पहले आता है। ROW_NUMBER() से पहले फ़िल्टर करने का अर्थ है "रिपोर्टिंग अंतराल में सबसे पहला visit," जो प्रॉम्प्ट से बिल्कुल मेल खाता है। विंडो क्रम में event_id जोड़ने से चयनित एंकर तब स्थिर रहता है जब visits एक टाइमस्टैम्प साझा करते हैं।
WITH ranked_visits AS (
SELECT
user_id,
event_id AS visit_event_id,
event_time AS visit_time,
ROW_NUMBER() OVER (
PARTITION BY user_id
ORDER BY event_time, event_id
) AS visit_rank
FROM events
WHERE event_name = 'visit'
AND event_time >= :start_at
AND event_time < :end_at
),
cohort AS (
SELECT user_id, visit_event_id, visit_time
FROM ranked_visits
WHERE visit_rank = 1
)
SELECT *
FROM cohort;मुख्य क्वेरी दो आश्रित lateral लुकअप का उपयोग करती है। PostgreSQL अपनी बाईं ओर की पंक्तियों के मानों के साथ एक lateral सबक्वेरी का मूल्यांकन करता है। LEFT JOIN LATERAL कोहोर्ट पंक्ति को तब सुरक्षित रखता है जब कोई योग्य इवेंट नहीं मिलता है, जो कि एक फ़नल के लिए बिल्कुल आवश्यक है: एक आगंतुक (visitor) जो कभी साइन अप नहीं करता है, वह भाजक में बना रहता है।
WITH ranked_visits AS (
SELECT
user_id,
event_id AS visit_event_id,
event_time AS visit_time,
ROW_NUMBER() OVER (
PARTITION BY user_id
ORDER BY event_time, event_id
) AS visit_rank
FROM events
WHERE event_name = 'visit'
AND event_time >= :start_at
AND event_time < :end_at
),
cohort AS (
SELECT user_id, visit_event_id, visit_time
FROM ranked_visits
WHERE visit_rank = 1
),
progress AS (
SELECT
c.user_id,
c.visit_time,
s.signup_time,
p.purchase_time
FROM cohort AS c
LEFT JOIN LATERAL (
SELECT
e.event_id AS signup_event_id,
e.event_time AS signup_time
FROM events AS e
WHERE e.user_id = c.user_id
AND e.event_name = 'signup'
AND (
e.event_time > c.visit_time
OR (
e.event_time = c.visit_time
AND e.event_id > c.visit_event_id
)
)
AND e.event_time <= c.visit_time + INTERVAL '24 hours'
ORDER BY e.event_time, e.event_id
LIMIT 1
) AS s ON TRUE
LEFT JOIN LATERAL (
SELECT e.event_time AS purchase_time
FROM events AS e
WHERE e.user_id = c.user_id
AND e.event_name = 'purchase'
AND s.signup_time IS NOT NULL
AND (
e.event_time > s.signup_time
OR (
e.event_time = s.signup_time
AND e.event_id > s.signup_event_id
)
)
AND e.event_time <= c.visit_time + INTERVAL '24 hours'
ORDER BY e.event_time, e.event_id
LIMIT 1
) AS p ON TRUE
)
SELECT
COUNT(*) AS visited_users,
COUNT(*) FILTER (WHERE signup_time IS NOT NULL) AS signed_up_users,
COUNT(*) FILTER (WHERE purchase_time IS NOT NULL) AS purchased_users,
ROUND(
COUNT(*) FILTER (WHERE signup_time IS NOT NULL)::numeric
/ NULLIF(COUNT(*), 0),
4
) AS signup_rate,
ROUND(
COUNT(*) FILTER (WHERE purchase_time IS NOT NULL)::numeric
/ NULLIF(COUNT(*), 0),
4
) AS purchase_rate
FROM progress;Signup लुकअप एक साथ तीन गुण साबित करता है: समान उपयोगकर्ता, एंकर के बाद सख्त टपल क्रम, और एंकर की 24 घंटे की विंडो में समावेशन। क्रमबद्धता और LIMIT 1 एक नियतात्मक इवेंट का चयन करते हैं। Purchase लुकअप उस चयनित signup पर निर्भर करता है, इसलिए इससे पहले की purchase को नजरअंदाज कर दिया जाता है जबकि बाद की मान्य purchase पात्र बनी रहती है। इसकी समय सीमा अभी भी c.visit_time को संदर्भित करती है; अन्यथा क्वेरी अनजाने में 48 घंटे तक का समय दे देगी।
यह लालची (greedy) विकल्प एक निश्चित तीन-चरणीय क्रमित फ़नल के लिए सही है। सबसे शुरुआती योग्य signup चुनने से ऐसी कोई purchase समाप्त नहीं हो सकती जिसे बाद का signup अनुमति दे सकता था: बाद के signup के बाद की कोई भी purchase पहले वाले signup के बाद भी होती है, और सामान्य समय सीमा अपरिवर्तित रहती है। यही तर्क सबसे शुरुआती योग्य purchase चुनने पर भी लागू होता है। प्रत्येक लुकअप के बाद का अपरिवर्तनीय नियम यह है कि चयनित श्रृंखला मान्य है और विंडो का सबसे बड़ा संभावित शेष भाग छोड़ती है।
progress CTE में प्रति कोहोर्ट उपयोगकर्ता ठीक एक पंक्ति होती है क्योंकि प्रत्येक lateral लुकअप अधिकतम एक पंक्ति लौटाता है। इसलिए फ़िल्टर किए गए एग्रीगेट DISTINCT की आवश्यकता के बिना उपयोगकर्ताओं की गणना करते हैं। Purchase की गणना signup की गणना से अधिक नहीं हो सकती, और signup की गणना visit की गणना से अधिक नहीं हो सकती। ये असमानताएं परिणाम-स्तरीय उपयोगी दावे (assertions) हैं।
आकर्षक दिखने वाले स्वतंत्र-न्यूनतम पैटर्न से बचें:
MIN(CASE WHEN event_name = 'signup' THEN event_time END),
MIN(CASE WHEN event_name = 'purchase' THEN event_time END)अनुक्रम visit(09:00), purchase(09:05), signup(09:10), purchase(09:20) के लिए, स्वतंत्र न्यूनतम 09:05 की purchase का चयन करते हैं और उपयोगकर्ता को अस्वीकार कर सकते हैं। आश्रित क्वेरी 09:10 के signup और फिर 09:20 की purchase का चयन करती है। सशर्त न्यूनतम केवल तभी काम कर सकते हैं जब प्रत्येक न्यूनतम पिछले चयनित चरण द्वारा विवश हो, जो कि यहाँ मुख्य कठिनाई है।
दो इंडेक्स प्रशंसनीय शुरुआती बिंदु हैं:
CREATE INDEX events_anchor_scan_idx
ON events (event_name, event_time, user_id, event_id);
CREATE INDEX events_user_step_lookup_idx
ON events (user_id, event_name, event_time, event_id);पहला कोहोर्ट बनाने के लिए उपयोग किए जाने वाले इवेंट-नाम और समय सीमा का समर्थन करता है। दूसरा बार-बार प्रति-उपयोगकर्ता चरण जांच का समर्थन करता है। वे स्टोरेज और राइट एम्प्लीफिकेशन जोड़ते हैं, और वास्तविक मूल्य चयनात्मकता (selectivity), क्लस्टरिंग, तालिका के आकार और PostgreSQL की चुनी गई योजना पर निर्भर करता है। प्रतिनिधि डेटा पर EXPLAIN (ANALYZE, BUFFERS) के साथ सत्यापित करें। लगातार बड़े पैमाने की रिपोर्टों के लिए, एक स्थिर अनुक्रम फ़ील्ड वाला इवेंट मॉडल या क्रमिक रूप से बनाए रखी जाने वाली उपयोगकर्ता-यात्रा तालिका अधिक उपयुक्त हो सकती है, लेकिन इसे समान कोहोर्ट और विंडो अनुबंध को बनाए रखना चाहिए।
एक कॉम्पैक्ट प्रतिकूल परीक्षण फिक्सचर में इन मामलों को शामिल किया जाना चाहिए:
1. purchase before visit -> visitor only
2. visit, purchase, signup -> signed up, not purchased
3. visit, purchase, signup, later purchase -> completes all steps
4. duplicate signups and purchases -> user still counts once per stage
5. purchase exactly at visit + 24 hours -> counts
6. purchase one microsecond after visit + 24 hours -> does not count
7. equal timestamps -> event_id determines sequence
8. repeated visits in the interval -> earliest visit remains the anchor
9. no visits -> zero counts and null ratesरिपोर्टिंग जीवनचक्र का भी परीक्षण करें। यदि end_at 1 जुलाई की मध्यरात्रि है, तो 30 जून को 23:59 पर आने वाला आगंतुक 1 जुलाई को 23:59 तक रूपांतरित हो सकता है। 1 जुलाई की मध्यरात्रि में किया गया निष्पादन अधूरा है। वॉल क्लॉक के बजाय इनजेशन वॉटरमार्क का उपयोग करें, और देर से इवेंट आने पर प्रभावित कोहोर्ट्स की पुनर्गणना करें।
उच्च गुणवत्ता वाला नमूना उत्तर
"मैं SQL लिखने से पहले एट्रिब्यूशन नियम बताऊंगा: प्रति उपयोगकर्ता एक फ़नल अवसर, जो रिपोर्टिंग अंतराल के भीतर उनके सबसे पहले visit पर एंकर है। अंतराल अर्ध-खुला है, बाद के चरण इसके समाप्त होने के बाद हो सकते हैं, और signup और purchase दोनों एंकर के 24 घंटों के भीतर होने चाहिए। समान टाइमस्टैम्प को गारंटीकृत इवेंट आईडी अनुक्रम द्वारा क्रमित किया जाता है।
मैं पहले visits को अंतराल के अनुसार फ़िल्टर करता हूँ, उन्हें प्रति उपयोगकर्ता (event_time, event_id) द्वारा रैंक करता हूँ, और रैंक एक रखता हूँ। यह सही भाजक ग्रेन देता है। प्रत्येक एंकर के लिए मैं सबसे शुरुआती मान्य signup प्राप्त करने के लिए उसी टपल द्वारा क्रमित एक left lateral सबक्वेरी का उपयोग करता हूँ। एक दूसरी left lateral सबक्वेरी चयनित signup को संदर्भित करती है और visit से जुड़ी समय सीमा को रखते हुए सबसे शुरुआती मान्य purchase प्राप्त करती है। चूंकि प्रत्येक लुकअप में LIMIT 1 है, इसलिए प्रगति संबंध प्रति आगंतुक एक पंक्ति बना रहता है। छूटे हुए चरण उपयोगकर्ता को हटाने के बजाय null रहते हैं।
अंतिम एग्रीगेट सभी प्रगति पंक्तियों की गणना करता है, फिर गैर-null signup और purchase टाइमस्टैम्प के लिए फ़िल्टर की गई गणनाओं का उपयोग करता है। दोनों दरें visit कोहोर्ट गणना से विभाजित होती हैं और खाली इनपुट के लिए NULLIF का उपयोग करती हैं। मैं purchased_users <= signed_up_users <= visited_users का दावा करूंगा, हर चरण के लिए नमूना श्रृंखलाओं का निरीक्षण करूंगा, और विशेष रूप से उल्टे इवेंट, दोहराए गए चरणों, समान टाइमस्टैम्प और 24-घंटे की सीमा के दोनों पक्षों का परीक्षण करूंगा।
उत्पादन के लिए, मैं नए कोहोर्ट को तब तक पूर्ण नहीं कहूंगा जब तक कि इनजेशन वॉटरमार्क उसके पूरे अवसर विंडो को कवर न कर ले। मैं एंकर स्कैन और प्रति-उपयोगकर्ता चरण लुकअप का समर्थन करने वाले इंडेक्स के साथ और उसके बिना निष्पादन योजनाओं की तुलना करूंगा। यदि टाइमस्टैम्प और इवेंट आईडी विश्वसनीय क्रम का प्रतिनिधित्व नहीं करते हैं, तो मैं रुक जाऊंगा और इवेंट अनुबंध को ठीक करूंगा क्योंकि क्वेरी छूटे हुए कारण-संबंध को पुनः प्राप्त नहीं कर सकती है।"
सामान्य गलतियाँ
- केवल इवेंट की उपस्थिति की जाँच करना। तीन इवेंट फ़्लैग
purchase → visit → signupकी गणना कर सकते हैं। एक फ़नल को
एक स्पष्ट क्रमित श्रृंखला की आवश्यकता होती है।
- स्वतंत्र प्रथम टाइमस्टैम्प लेना। सबसे शुरुआती purchase चयनित signup से पहले हो सकती है, भले ही
बाद की purchase एक मान्य यात्रा पूरी करती हो।
- अनजाने में हर visit को एंकर करना। यह ग्रेन को एक उपयोगकर्ता अवसर से एक visit अवसर में बदल देता है
और किसी उपयोगकर्ता को अलग तरीके से गिन या एट्रिब्यूट कर सकता है।
- क्रमबद्ध करने के लिए केवल
event_timeका उपयोग करना। समान टाइमस्टैम्प परिणाम को अस्थिर बनाते हैं। एक विश्वसनीय
अनुक्रम कुंजी का उपयोग करें या स्वीकार करें कि क्रम अज्ञात है।
- प्रत्येक चरण पर विंडो को पुनरारंभ करना। Signup को 24 घंटे और purchase को अन्य 24 घंटे देना
एंकर-आधारित 24-घंटे के अनुबंध का उल्लंघन करता है।
end_atद्वारा बाद के चरणों को फ़िल्टर करना। यह रिपोर्टिंग सीमा के करीब आने वाले आगंतुकों के लिए अवसर
को छोटा करता है। प्रत्येक एंकर की समय सीमा के माध्यम से बाद के इवेंट प्राप्त करें।
- Inner lateral join का उपयोग करना। बिना signup वाले आगंतुक गायब हो जाते हैं, जिससे रूपांतरण दर बढ़ जाती है।
- रॉ इवेंट पंक्तियों की गणना करना। पुनः प्रयास और दोहराई गई कार्रवाइयां स्टेज गणनाओं को कोहोर्ट आकार से अधिक कर सकती हैं।
- गलती से पिछले चरण से विभाजित करना। यह एक चरण रूपांतरण दर की गणना करता है, visits से बताई गई
संचयी दर की नहीं।
- एक अपरिपक्व कोहोर्ट प्रकाशित करना। बाद के इवेंट की अनुपस्थिति ड्रॉप-ऑफ का प्रमाण नहीं है जब तक कि
पूरी विंडो विश्वसनीय डेटा द्वारा कवर न हो जाए।
अनुवर्ती प्रश्न और उत्तर
क्या होगा यदि कोई भी visit एक मान्य यात्रा शुरू कर सकता है?
ग्रेन बदल जाता है। प्रत्येक visit के लिए उम्मीदवार एंकर बनाएं, प्रत्येक से एक मान्य श्रृंखला का मिलान करें, और फिर प्रति उपयोगकर्ता सबसे पहले पूरी हुई यात्रा जैसा एट्रिब्यूशन नियम लागू करें। केवल एंकर CTE को प्रतिस्थापित न करें: ओवरलैपिंग विंडो एक ही बाद के इवेंट के लिए प्रतिस्पर्धा कर सकती हैं, इसलिए उत्पाद अनुबंध में यह बताया जाना चाहिए कि क्या पुन: उपयोग की अनुमति है।
क्या होगा यदि प्रत्येक चरण को एक सत्र (session) या उत्पाद साझा करना पड़े?
एंकर से सहसंबंध कुंजी (correlation key) आगे ले जाएं और दोनों lateral लुकअप में इसकी आवश्यकता रखें। ग्रेन केवल उपयोगकर्ता के बजाय उपयोगकर्ता-सत्र या उपयोगकर्ता-उत्पाद बन जाता है। जॉइन पर निर्भर रहने से पहले परिभाषित करें कि null कुंजियाँ कैसा व्यवहार करती हैं और क्या कुंजी अपरिवर्तनीय है।
आप दस फ़नल चरणों का समर्थन कैसे करेंगे?
हाथ से लिखे गए दस lateral जॉइन का ऑडिट करना कठिन है। डेटाबेस के आधार पर, रिकर्सिव SQL, एक नेटिव अनुक्रम या फ़नल फ़ंक्शन, या एक प्रीप्रोसेसिंग कार्य का उपयोग करें जो स्टेट मशीन के रूप में क्रमित इवेंट्स को प्रोसेस करता है। उन्हीं अपरिवर्तनीयों को बनाए रखें: एक परिभाषित एंकर, मोनोटोनिक चरण क्रम, एक साझा समय सीमा, और एक ऑडिट योग्य एट्रिब्यूशन नियम।
क्या होगा यदि इवेंट देर से या क्रम से बाहर आते हैं?
इवेंट समय को इनजेशन समय से अलग करें, एक पूर्णता वॉटरमार्क प्रकाशित करें, और उन कोहोर्ट्स को पुनः व्यवस्थित करें जिनकी विंडो देर से डेटा प्राप्त करती हैं। आने के बाद भी इवेंट-समय क्रम की गणना की जा सकती है, लेकिन सहमत विलंबता अंतराल बीत जाने तक रिपोर्ट अनंतिम रहती है।
क्या एक विंडो फ़ंक्शन पूरी समस्या को हल कर सकता है?
यह कर सकता है, उदाहरण के लिए प्रत्येक उपयोगकर्ता के क्रमित स्ट्रीम को स्कैन करके और स्थिति को आगे ले जाकर, लेकिन अकेले LAG पर्याप्त नहीं है क्योंकि चरणों के बीच अप्रासंगिक और डुप्लिकेट इवेंट हो सकते हैं। Lateral समाधान चयनित चरणों के बीच निर्भरता को स्पष्ट करता है। किसी अन्य सूत्रीकरण को केवल तभी चुनें जब उसके स्थिति संक्रमण (state transitions) और एट्रिब्यूशन सिमेंटिक्स समान रूप से स्पष्ट हों और उसकी मापी गई योजना बेहतर हो।