Postgresql - 有关join的where子句的条件

时间:2017-02-10 13:17:03

标签: postgresql join where-clause

我正在尝试为我的查询添加特定条件的连接:

select *
from (
    select
        row_number() over (partition by dl.value order by random()) as rn,
        dl.value,
        q.question_text, q.option_a, q.option_b, q.option_c, q.option_d,
        q.correct_answer, q.image_link, q.question_type
    from
        questions_bank q
        inner join
        sports_type st on st.id = q.sports_type_id
        inner join
        difficulty_level dl on dl.id = q.difficulty_level_id
    where st.game_type = lower('cricket') and dl.value in ('E','M','H')
) s
where 
    value = 'E' and rn <= 7 or
    value = 'M' and rn <= 4 or
    value = 'H' and rn = 1

因此,如果值=&#39; E&#39;这些问题中有50%(7)应该来自“&#39; general&#39;问题类别。

&#34; case when dl.value='E' then rn=4 (50% of 7) from question_category='general', 3 (7-4) else 7 end&#34;

(我需要添加INNER JOIN question_category qc ON qc.id = q.question_category_id

之类的连接

对于其他值(M / H),不应该与question_category

进行任何联接

请参阅question以查看原始问题。

更新:

我正在尝试:

select *                                                          
   from (
          select
                row_number() over (partition by dl.value order by random()) as rn,
                row_number() over (partition by dl.value, LOWER(qc.value) = LOWER('general') order by random()) as rnc,
                dl.value, qc.value as question_category,
                q.question_text, q.option_a, q.option_b, q.option_c, q.option_d,
                q.correct_answer, q.image_link, q.question_type
            from
                questions_bank q
                inner join
                question_category qc on qc.id = q.question_category_id
                inner join
                sports_type st on st.id = q.sports_type_id
                inner join
                difficulty_level dl on dl.id = q.difficulty_level_id
            where st.game_type = lower('cricket') and dl.value in ('E','M','H')
        ) s
   where
        (value = 'E' and rnc <= 4) or (value = 'E' and rn <= 3)or
        value = 'M' and rn <= 3 or
        value = 'H' and rn <= 2;

但这会为值=&#39; E&#39;返回额外的行。 (4来自rnc,4来自rn,当值=&#39; E&#39;)。我错过了什么?

3 个答案:

答案 0 :(得分:0)

SELECT *
FROM (
    SELECT
        row_number() over (partition by dl.value order by random()) as rn
        , dl.value
        , q.question_text, q.option_a, q.option_b, q.option_c, q.option_d
        , q.correct_answer, q.image_link, q.question_type
    FROM
        questions_bank q
        JOIN sports_type st ON st.id = q.sports_type_id
        JOIN difficulty_level dl ON dl.id = q.difficulty_level_id
    WHERE st.game_type = lower('cricket') AND dl.value IN ('E','M','H')
    AND ( dl.value = 'E'    -- No extra condition for 'E'
        OR EXISTS           -- Extra condition for non-'E'
          (SELECT * FROM question_category qc
          WHERE qc.id = q.question_category_id
          )
        )
) s
WHERE value = 'E' AND rn <= 7 
   or value = 'M' AND rn <= 4 
   or value = 'H' AND rn = 1
        ;

答案 1 :(得分:0)

我为general类别提供了1个ID。必要时更换。

select *
from (
    select
        row_number() over (partition by dl.value order by random()) as rn,
        row_number() over (
            partition by dl.value, question_category_id = 1
            order by random()
        ) as rnc,
        dl.value,
        q.question_text, q.option_a, q.option_b, q.option_c, q.option_d,
        q.correct_answer, q.image_link, q.question_type
    from
        questions_bank q
        inner join
        sports_type st on st.id = q.sports_type_id
        inner join
        difficulty_level dl on dl.id = q.difficulty_level_id
        inner join
        question_category qc on qc.id = q.question_category_id
    where st.game_type = lower('cricket') and dl.value in ('E','M','H')
) s
where 
    value = 'E' and rn <= 4 or
    value = 'M' and rnc <= 4 or
    value = 'H' and rn = 1

答案 2 :(得分:0)

我可以找到方法,

以下是我的想法。

select *
                from (
                    select
                        row_number() over (partition by dl.value order by random()) as rn,
                        row_number() over (partition by dl.value, LOWER(qc.value) = LOWER('general') order by random()) as rnc,
                        row_number() over (partition by dl.value, LOWER(qc.value) != LOWER('general') order by random()) as rnq,
                        dl.value, qc.value as question_category,
                        q.question_text, q.option_a, q.option_b, q.option_c, q.option_d,
                        q.correct_answer, q.image_link, q.question_type
                    from
                        questions_bank q
                        inner join
                        question_category qc on qc.id = q.question_category_id
                        inner join
                        sports_type st on st.id = q.sports_type_id
                        inner join
                        difficulty_level dl on dl.id = q.difficulty_level_id
                    where st.game_type = lower('cricket') and dl.value in ('E','M','H')
                ) s
                where
                    (value = 'E' and rnq <= 4 and LOWER(question_category) != LOWER('general')) or
                    (value = 'E' and rnc <= 3 and LOWER(question_category) = LOWER('general')) or
                    value = 'M' and rn <= 3 or
                    value = 'H' and rn <= 2