【问题标题】:SQL select odd rows after sorting by multiple columns in different orderSQL按多列以不同顺序排序后选择奇数行
【发布时间】:2021-11-05 16:38:44
【问题描述】:

我有一个学生表(id、分数、部门)和部门表(id、名称)。我正在尝试向查询中添加某些条件。

学校部门

+---------+-------------+
| dept_id | name        |
+---------+-------------+
| 1       | Admin       |
+---------+-------------+
| 2       | Chemistry   |
+---------+-------------+
| 3       | Physics     |
+---------+-------------+
| 4       | Biology     |
+---------+-------------+
| 5       | Mathematics |
+---------+-------------+

学生

+------------+-------+------------+
| student_id | score | department |
+------------+-------+------------+
| 26         | 11    | 4          |
+------------+-------+------------+
| 34         | 11    | 3          |
+------------+-------+------------+
| 76         | 11    | 2          |
+------------+-------+------------+
| 49         | 11    | 1          |
+------------+-------+------------+
| 38         | 11    | 5          |
+------------+-------+------------+

 
  • 选择所有少于 5 名学生的 school_depts
  • 按学生总分降序排列学校部门。如果出现平局,则获得该部门最多的学生将是第一;如果仍然存在平局,则应首先使用具有最小 dept_id 的部门。
  • 只考虑奇数行,排除偶数行

我的尝试

SELECT * FROM (
SELECT * , ROW_NUMBER() OVER() AS ROW_ID FROM (
SELECT dept_id, name, count(E.student_id) as total_students, SUM(score) as total_score
from Students E
LEFT JOIN school_dept D on dept_id=student_id
group by 1,2
) as O
WHERE total_students<3
order by total_score desc, total_students desc, dept_id asc
) as U
WHERE ROW_ID %2 <>0

预期输出是

name, total_students, total_score
Admin,1,11
Physics1,11
Mathematics,1,11

http://sqlfiddle.com/#!17/248eb8/2

【问题讨论】:

    标签: sql sql-server sorting tsql


    【解决方案1】:

    我认为您的查询中存在连接问题(将 student_iddept_id 连接),并且您选择的学生少于 三个 (但要求要求少于 五个 学生)。

    请尝试以下方法:

    select department as "name", total_students, total_score
    from
    (
        select *, row_number() over (order by total_score desc, total_students desc, dept_id) row_id
        from
        (
            select sum(score) total_score, count(student_id) total_students, sd.name department, sd.dept_id
            from students s
            join school_dept sd on s.department = sd.dept_id
            group by 3,4
            having count(student_id) < 5
        )t
    )tt
    where row_id%2 <> 0
    

    请参阅 SQL Fiddle here

    【讨论】:

      【解决方案2】:

      由于 School_dept 是部门的父表,所以 JOINING 将 School_dept Left 加入学生。因为一个部门可能没有学生,所以左加入是完美的。但是如果考虑那些有学生的部门然后使用 INNER JOIN。

      -- SQL SERVER (v2017)
      SELECT p.dept_name "Name", p.total_students, p.total_score
      FROM (SELECT *
                 , ROW_NUMBER() OVER (ORDER BY t.total_score DESC, t.total_students DESC, t.dept_id) row_num
            FROM (SELECT sd.dept_id
                       , MAX(sd.name) dept_name
                       , COUNT(s.student_id) total_students
                       , SUM(s.score) total_score
                  FROM School_dept sd
                  LEFT JOIN Students s
                         ON sd.dept_id = s.department
                  GROUP BY sd.dept_id
                  HAVING COUNT(s.student_id) < 5) t) p
      WHERE (p.row_num % 2) != 0;
      

      请查看网址https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=abf4b40f692d085b98054aa9c9a1dcc7

      【讨论】:

      • @shockwave 请检查这个答案。如果对您有帮助,请告诉我。
      【解决方案3】:

      我认为下面的查询应该可以工作

      select *,
      Rank() over  (order by Score desc,TotalStudent desc,dept_id asc) as Serial
      from
      (
      select d.dept_id,d.Name,COUNT(student_id) TotalStudent,sum(Score) Score
      
      from Students s
      left join School_dept d on s.department=d.dept_id
      where d.dept_id % 2 <> 0
      group by d.Name,d.dept_id
      ) a where TotalStudent < 5
      

      【讨论】:

        猜你喜欢
        • 2015-03-08
        • 2011-07-01
        • 1970-01-01
        • 2021-03-27
        • 2016-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-02
        相关资源
        最近更新 更多