Sql 单行中有多条记录

Sql 单行中有多条记录,sql,postgresql,Sql,Postgresql,我的数据库中有学生的毕业后学位记录。学生可能只有一个毕业后学位,有些学生可能有一个以上的毕业后学位 rollno | pgdegree | score -------------------------- 0001 | 41 | 56 0002 | 42 | 78 0002 | 49 | 75 0003 | 48 | 77 此处,第0002卷不止一次,第00010003卷只有一次 我希望我的期望输出为: rollno | pgde

我的数据库中有学生的毕业后学位记录。学生可能只有一个毕业后学位,有些学生可能有一个以上的毕业后学位

rollno | pgdegree | score
--------------------------
0001   | 41       | 56
0002   | 42       | 78
0002   | 49       | 75
0003   | 48       | 77
此处,第0002卷不止一次,第00010003卷只有一次

我希望我的期望输出为:

rollno | pgdegree1 | score1 | pgdegree2 | score2
------------------------------------------------
0001   | 41        | 56     |           | 
0002   | 42        | 78     | 49        | 75
0003   | 48        | 77     |           |
注意:在我的数据库中,任何学生只能有一个或两个后分级。不超过两个PG学位


您可以使用巧妙的透视查询:

SELECT t.rollno,
    SUM(CASE WHEN pgdegree = (SELECT MIN(pgdegree) FROM yourTable WHERE rollno = t.rollno)
             THEN pgdegree ELSE 0 END) AS pgdegree1,
    SUM(CASE WHEN pgdegree = (SELECT MIN(pgdegree) FROM yourTable WHERE rollno = t.rollno)
             THEN score ELSE 0 END) AS score1,
    SUM(CASE WHEN pgdegree = (SELECT MAX(pgdegree) FROM yourTable WHERE rollno = t.rollno)
             THEN pgdegree ELSE 0 END) AS pgdegree2,
    SUM(CASE WHEN pgdegree = (SELECT MAX(pgdegree) FROM yourTable WHERE rollno = t.rollno)
             THEN score ELSE 0 END) AS score2
FROM yourTable t
GROUP BY t.rollno
说明:


前两个CASE语句具有子查询,如果该值恰好是给定rollno的最小值,则该子查询将返回pgdegree。此pgdegree和score将显示为前两列。类似地,最后两个CASE语句使用最大值生成后两列。

下面是另一个解决方案,使用行数和条件聚合来保存一些不必要的选择:

SELECT s.rollno,
       MAX(CASE WHEN s.rnk = 1 THEN s.pgdegree END) AS pgdegree1, 
       MAX(CASE WHEN s.rnk = 1 THEN s.score    END) AS score1, 
       MAX(CASE WHEN s.rnk = 2 THEN s.pgdegree END) AS pgdegree2, 
       MAX(CASE WHEN s.rnk = 2 THEN s.score    END) AS score2
FROM
(
    SELECT t.*,
           ROW_NUMBER() OVER (PARTITION BY t.rollno ORDER BY t.pgdegree, t.score) AS rnk
    FROM YourTable t
) s
GROUP BY s.rollno
如果可用于rollno,则执行自左连接以添加第二个pgdegree。“不存在”仅将pgdegree最低的行返回为t1.pgdegree

select t1.rollno, t1.pgdegree, t1.score, t2.pgdegree, t2.score
from tablename t1
  left join tablename t2
      on t1.rollno = t2.rollno and t1.pgdegree < t2.pgdegree
where not exists (select * from tablename t3
                  where t1.rollno = t3.rollno
                    and t1.pgdegree > t3.pgdegree)

如果您正好有一个或两个PG,则可以使用rollno和打印PGDEGRE和score将原始表和联接表本身联接起来。相反:只有一个PG的学生pgdegree1和pgdegree2的得分分别为1和2。美国最大的大学的招生人数略高于6万。对于2度,最多乘以2。我不认为100K这么大,这个查询应该是一个大问题。我不是在谈论100K记录:其他人也可以看到这一点,他们的表可能不同。“这确实回答了这个问题,可能会很有用。”阿贝利斯读了这个问题:在我的数据库中,任何学生都只能有一到两个分级后考试。不超过两个PG学位。。。否则我不会建议pivot查询。您的查询没有给出确切的结果。我在表中有4529个不同的卷号,但您的查询结果是4614行。我接受的答案是提供准确的记录。@DhairyaLakhera,您是否有rollno/pgdegree副本?
select
  rollno,
  (array_agg(pgdegree))[1] as pgdegree1,
  (array_agg(score))[1] as score1,
  (array_agg(pgdegree))[2] as pgdegree2,
  (array_agg(score))[2] as score2
from
  your_table
group by
  rollno;