如果特定列不是 order by 语句的一部分,如何按特定列跳过行

问题描述 投票:0回答:1

我正在使用 PostgreSQL 14.13。

这是一个小提琴:https://www.db-fiddle.com/f/wtCiz8QtBSkZ3WyS8vRDkQ/0

我有一个查询,可以为学生以智能方式订购卡片

select setseed(-0.07687704123439676);
SELECT cards.id,
       dc.deck_id,
       cards.question,
       cards.answer,
       uc.practice_session_sr_level
FROM cards
         LEFT JOIN decks_cards dc ON cards.id = dc.card_id
         LEFT JOIN user_card uc ON cards.id = uc.card_id

WHERE dc.deck_id = 2907
GROUP BY cards.id,
         uc.practice_session_sr_level,
         dc.deck_id
ORDER BY
    --   cards.id = 98486 desc,
         practice_session_sr_level = 'NOT_LEARNED' DESC,
         practice_session_sr_level = 'AGAIN' DESC,
         practice_session_sr_level = 'HARD' DESC,
         practice_session_sr_level = 'EASY' DESC,
         practice_session_sr_level = 'GOOD' DESC,
         RANDOM()
LIMIT 10 OFFSET 0;

这给了我这样的结果:

98512,2907,How do you say 'family'?,rodzina,NOT_LEARNED
98498,2907,How do you say 'teacher' in Polish?,nauczyciel,NOT_LEARNED
98580,2907,What is the Polish word for 'forest'?,las,NOT_LEARNED
98486,2907,How do you say 'friend' in Polish?,przyjaciel,NOT_LEARNED
98525,2907,What is the Polish word for 'heart'?,serce,NOT_LEARNED
98528,2907,How do you say 'solution' in Polish?,rozwiązanie,NOT_LEARNED
98497,2907,What is the Polish word for 'school'?,szkoła,NOT_LEARNED
98540,2907,How do you say 'drink' in Polish?,napój,NOT_LEARNED
...

我想让用户按下一张卡片并开始从该卡片开始学习。

例如,如果用户按下 id

98486
的卡片,则应跳过该卡片之前的卡片。

如果我取消评论

cards.id = 98486 desc,
我明白了

当前结果

98486,2907,How do you say 'friend' in Polish?,przyjaciel,NOT_LEARNED
98512,2907,How do you say 'family'?,rodzina,NOT_LEARNED
98498,2907,How do you say 'teacher' in Polish?,nauczyciel,NOT_LEARNED
98580,2907,What is the Polish word for 'forest'?,las,NOT_LEARNED
98525,2907,What is the Polish word for 'heart'?,serce,NOT_LEARNED
98528,2907,How do you say 'solution' in Polish?,rozwiązanie,NOT_LEARNED
98497,2907,What is the Polish word for 'school'?,szkoła,NOT_LEARNED
98540,2907,How do you say 'drink' in Polish?,napój,NOT_LEARNED
...

预期结果

98486,2907,How do you say 'friend' in Polish?,przyjaciel,NOT_LEARNED
98525,2907,What is the Polish word for 'heart'?,serce,NOT_LEARNED
98528,2907,How do you say 'solution' in Polish?,rozwiązanie,NOT_LEARNED
98497,2907,What is the Polish word for 'school'?,szkoła,NOT_LEARNED
98540,2907,How do you say 'drink' in Polish?,napój,NOT_LEARNED
...

如何更新查询以便 PostgreSQL 可以跳过指定 id 之前的行?

sql postgresql
1个回答
0
投票
  • 不要
    order by random() limit 10
    。请改用
    tablesample
    子句。
  • 如果
    practice_session_sr_level
    是一个枚举,则其中的值具有隐含的数值/排序顺序。您可以重新排列枚举类型定义(或者创建一个,如果它还不是枚举)以
    ('NOT_LEARNED','AGAIN','HARD','EASY','GOOD')
    
    这简化了订购
    order by practice_session_sr_level;
    
    这也比计算 5 个表达式要快得多,无论多么简单。
  • @Luuk立即建议使用
    row_number()over(..)
    是正确的:
    db<>fiddle的演示
    SELECT row_number()over w1,
            cards.id,
            dc.deck_id,
            cards.question,
            cards.answer,
            uc.practice_session_sr_level
     FROM cards
              LEFT JOIN decks_cards dc ON cards.id = dc.card_id
              LEFT JOIN user_card uc ON cards.id = uc.card_id
     WHERE dc.deck_id = 2907
     GROUP BY cards.id,
              uc.practice_session_sr_level,
              dc.deck_id
     WINDOW w1 AS(ORDER BY cards.id = 98497 desc,
                           practice_session_sr_level = 'NOT_LEARNED' DESC,
                           practice_session_sr_level = 'AGAIN' DESC,
                           practice_session_sr_level = 'HARD' DESC,
                           practice_session_sr_level = 'EASY' DESC,
                           practice_session_sr_level = 'GOOD' DESC,
                           RANDOM() )
     ORDER BY row_number
     LIMIT 10 OFFSET 4/*the 4 is taken from the row_number clicked*/-1;
    
    您还可以将整个内容包装在子查询中并使用
    where row_number>=4
© www.soinside.com 2019 - 2024. All rights reserved.