不同行的多条件

multi condition on different rows

age | name     | course | score
_________________________
10  |James    | Math   | 10
10  |James    | Lab    | 15
12  |Oliver   | Math   | 15
13  |William  | Lab    | 13 

我想要 select 记录数学 >= 10 和实验室 >11 我写这个查询

select * from mytable
where (course='Math' and score>10) and  (course='Lab' and score>11) 

但是这个查询没有return任何记录。

我想要这个结果

age | name     
____________
10  |James   

其中条件(数学 >= 10 和实验室 >11)是动态生成的,可能有 2 个条件或 100 个或更多...

请帮帮我

您查询查找同时满足两个条件的记录 - 这是不可能发生的,因为每条记录都有一个课程。

您想要一个适用于具有相同名称的行的条件,因此建议改为聚合:

select age, name 
from mytable
where course in ('Math', 'Lab')
group by age, name 
having
    max(case when course = 'Math' then score end) > 10
    and max(case when course = 'Lab' then score end) > 11

如果您将问题表述为:

  1. Select 所有唯一(姓名、年龄)组合
  2. 数学课程有一行分数 >= 10
  3. 课程 Lab 的分数 > 11

然后你可以将其翻译成与 SQL 非常相似的内容:

select distinct t1.age, t1.name            -- unique combinations
from mytable t1
where exists ( select top 1 'x'            -- with a row math score >= 10
               from mytable t2
               where t2.name = t1.name
                 and t2.age = t1.age
                 and t2.course = 'math'
                 and t2.score >= 10 )
  and exists ( select top 1 'x'            -- with a row lab score > 11
               from mytable t3
               where t3.name = t1.name
                 and t3.age = t1.age
                 and t3.course = 'lab'
                 and t3.score > 11 );

我认为您的数据或条件不适合您的输出。尽管根据您的条件,您可以单独使用您的条件,然后从两个选择中使用相交并获取过滤后的数据。喜欢下面的代码。

select Age,Name
from Table_1
where Course ='Math' and Score>=10
INTERSECT
select Age,Name
from Table_1
where Course ='Lab' and Score>11

您可以使用关联子查询编写查询

select * from table_1 t1
    where score >11 and course ='lab' 
        and [name] in (select [name] from table_1 t2 where t1.[name] =t2.[name] and t1.age =t2.Age
        and t2.Score >=10 and course = 'Math')

如果需要名称,请使用聚合和 having 子句:

select name, age
from mytable
where (course = 'Math' and score > 10) or
      (course = 'Lab' and score > 11) 
group by name, age
having count(distinct course) = 2;

如需详细记录,使用window函数:

select t.*
from (select t.*,
             (dense_rank() over (partition by name, age order by course asc) +
              dense_rank() over (partition by name, age order by course desc)
             ) as cnt_unique_courses
      from mytable t
      where (course = 'Math' and score > 10) or
            (course = 'Lab' and score > 11) 
     ) t
where cnt_unique_courses = 2;

SQL 服务器不支持 count(distinct) 作为 window 函数。但是你可以通过使用 dense_rank() 两次来实现它。