如何获得至少注册一次的学生列表,然后最终状态为未注册?

nbewdwxp  于 2021-07-24  发布在  Java
关注(0)|答案(3)|浏览(203)

我有下表,它有学生谁登记和登记日期明智的日志。

student_id | is_enrolled | created_at
-------------------------------------
1          | 1           | 2020-01-01
2          | 0           | 2020-01-02
3          | 0           | 2020-01-01
1          | 0           | 2020-01-02
4          | 1           | 2020-01-02
1          | 0           | 2020-01-03
3          | 0           | 2020-01-03
4          | 1           | 2020-01-04

如果你看到了,学生1已经注册了 2020-01-01 然后在 2020-01-02 . 学生2和3从未入学。学生4多次入学,但从未退学。因此,不在输出中。
基本上,我想写一个查询,它的输出是学生喜欢的 1 ,至少注册过一次,但最终状态未注册。我本来可以招收所有的学生,但在那之后就被困了。
我的问题,

SELECT DISTINCT student_id 
  FROM student 
 WHERE is_enrolled = 1 
 ORDER
    BY student_id; # gives me 1 and 4

sql小提琴
理想情况下,一个没有嵌套查询的单一查询解决方案会非常棒。我对多重查询解决方案也没意见。
注意:我可以通过在代码中使用for循环来获得所需的输出,但是我想了解我是否可以通过sql查询来实现这一点。我不是在找任何编程语言代码。

njthzxwz

njthzxwz1#

SELECT DISTINCT x.* 
  FROM student x
  JOIN 
     ( SELECT student_id
            , MAX(created_at) created_at
         FROM student
        GROUP
           BY student_id
     ) y
    ON y.student_id = x.student_id
   AND y.created_at = x.created_at
  JOIN student z
    ON z.student_id = x.student_id
   AND z.is_enrolled = 1
 WHERE x.is_enrolled = 0;

作为旁白,千万不要用 SELECT * ,并且在没有任何聚合函数的情况下,GROUPBY子句是不合适的。

kcugc4gi

kcugc4gi2#

我不是dba(数据库Maven),但我通常会在我的mssql数据库中使用以下内容:

WITH summary AS (
SELECT 
  student_id, 
  is_enrolled, 
  created_at
  ROW_NUMBER() OVER(PARTITION BY s.student_id ORDER BY s.created_at DESC) AS rk
  FROM student s)
SELECT s.*
FROM summary s
WHERE s.rk = 1
AND is_enrolled = 1

我所做的是在order by完成后添加一个额外的列,您需要查看最新创建的值是否为1。
“with”部分用于定义子查询,其中包含一些额外的逻辑。

4ngedf3f

4ngedf3f3#

您可以使用aggregation:

select student_id
from student s
group by student_id
having sum(is_enrolled) >= 1 and
       max(created_at) = max(case when is_enrolled = 0 then created_at end);

第一个条件检查学生是否至少注册一次。
第二个检查最新的 created_at 是最新的吗 created_at 为了一张未登记的唱片。检查最后一个状态是否为“unrolled”。
这是sql小提琴。

相关问题