简体   繁体   中英

How to: SELECT from multiple CTEs that are mutually exclusive

I am in a situation where I need to show stats of a user based on referrals that user made & then stats about those referred users' activities. So, if user A refers user B, C then it means user A referred 2 users. Now, I need to get how many of those referred users did take an action ie PURCHASED. But they may not purchase which counts to 0. I have following query using CTEs which does work as expected but it also returns some false negative results. ie


    WITH direct_referrals AS (
        SELECT id
        FROM "user"
        WHERE "user"."referredBy" = ${userId}
    ),
    application_stats AS (
        SELECT count(status), status
        FROM "application"
        WHERE "userId" IN (SELECT id FROM direct_referrals)
        GROUP BY status
    )
          
    SELECT *, (SELECT count(id) FROM direct_referrals) AS "totalReferrals" 
    FROM application_stats;

This query returns correct result if at-least 1 referred user took some action but it fails when none has taken any action in which case this query returns the referred users to be 0 which is not true.

I can see that SELECT is dependent on application_stats CTE which may not return any result & hence the direct_referrals are also not returned. I am somewhat new to SQL so don't really know many options. Any help is appreciated.

Thanks

Update with sample Data & Expected Results

// User model

Id    username    referredBy
----  --------  -------------------
1     jon       NULL
2     jane      1
3     doe       1
4     smith     2
5     john      1

// Application model

Id    userId    status
----  --------  -------------------
1     12       'APPLIED'
2     13       'APPLIED'
3     14       'VIEWED'

Expected Result (for userId = 1):

User (referral) stats  Application stats
-------------------    -------------------
3                      0

Actual Result:

User (referral) stats  Application stats
-------------------    -------------------
0                      0

Something like this should give you what you want:

WITH REFERRAL AS (
    SELECT REFERREDBY, COUNT(USERNAME) AS "REF_CNT"
    FROM  USER_MODEL
    WHERE REFERREDBY IS NOT NULL
  GROUP BY REFERREDBY
),
APPLICATIONS AS (
    SELECT UM.REFERREDBY, COUNT(ML.APPL_STATUS) AS "APPL_CNT"
    FROM USER_MODEL UM
    LEFT OUTER JOIN APPLICATION_MODEL ML ON UM.ID = ML.USER_ID AND ML.APPL_STATUS = 'PURCHASED'
    GROUP BY UM.REFERREDBY
)
SELECT R.REFERREDBY, R.REF_CNT, A.APPL_CNT
FROM REFERRAL R
LEFT OUTER JOIN APPLICATIONS A ON R.REFERREDBY = A.REFERREDBY;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM