English 中文(简体)
为什么用“不是”条款中的某处不按预期行事?
原标题:Why does this SQL query with a `where not in` clause not work as expected?
  • 时间:2023-12-24 02:31:16
  •  标签:
  • mysql

http://www.db-fiddle.com/f/5oPihy8pysUfUGMPA9GNMC/0"rel=“nofollow noreferer”>SQL Fiddle。

这些是投入表:

学生表:

student_id student_name
1 Daniel
2 Jade
3 Stella
4 Jonathan
5 Will

表格:

exam_id student_id score
10 1 70
10 2 80
10 3 90
20 1 80
30 1 70
30 3 80
30 4 90
40 1 60
40 2 70
40 4 80

我需要找到“静坐”学生。 普通学生至少参加一次考试,未得分最高或最低。 我需要撰写一份解决办法,报告在<><<>all>/strong>考试中度过的学生(学生姓名)。 从未参加过考试的学生不得参加考试。

就此而言,这是一个先谈问题,我已经通过其他手段解决了这一问题。 我特别想理解以下提问为什么不可行。

with student_scores as (
select student_id, student_name, 
rank() over (partition by exam_id order by score asc) worse_rank,
rank() over (partition by exam_id order by score desc) best_rank

from Student
inner join Exam using (student_id)
)

select distinct student_id, student_name
from student_scores
where student_id not in (

select student_id
from student_scores
where ((worse_rank=1) or (best_rank=1)) and (student_id is not null)
)

However, this returns no record whereas I am expecting the record for student_id 2, Jade.

我在总结时发现的一些情况:

  1. It works if I use another CTE like so:
loud as (
  select distinct student_id
  from student_scores
  where ((worse_rank=1) or (best_rank=1)) and (student_id is not null)
)

之后使用

where student_id not in (select student_id from loud)

但是,如果我用别的在外语中的话,这只会奏效!

  1. It works if I create the input tables by explicitly defining student_id as the PRIMARY KEY.
  2. It also works if I use student_name in the where not in clause instead of student_id.
  3. Adding distinct to the subquery after the where not in clause does not help.
问题回答

I would use an aggregation approach here, with the help of the RANK() window function:

WITH cte AS (
    SELECT *, RANK() OVER (PARTITION BY exam_id ORDER BY score) rnk1,
              RANK() OVER (PARTITION BY exam_id ORDER BY score DESC) rnk2
    FROM Exam
)

SELECT s.student_id, s.student_name
FROM Student s
INNER JOIN cte t
    ON t.student_id = s.student_id
GROUP BY s.student_id, s.student_name
HAVING SUM(t.rnk1 = 1) = 0 AND SUM(t.rnk2 = 1) = 0;

条款》规定,任何对等学生在任何考试中都不是最低或最高评分。





相关问题
SQL SubQuery getting particular column

I noticed that there were some threads with similar questions, and I did look through them but did not really get a convincing answer. Here s my question: The subquery below returns a Table with 3 ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

php return a specific row from query

Is it possible in php to return a specific row of data from a mysql query? None of the fetch statements that I ve found return a 2 dimensional array to access specific rows. I want to be able to ...

Character Encodings in PHP and MySQL

Our website was developed with a meta tag set to... <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> This works fine for M-dashes and special quotes, etc. However, I ...

Pagination Strategies for Complex (slow) Datasets

What are some of the strategies being used for pagination of data sets that involve complex queries? count(*) takes ~1.5 sec so we don t want to hit the DB for every page view. Currently there are ~...

Averaging a total in mySQL

My table looks like person_id | car_id | miles ------------------------------ 1 | 1 | 100 1 | 2 | 200 2 | 3 | 1000 2 | 4 | 500 I need to ...

热门标签