aofeng811
2009-12-24 16:56
浏览 386
已采纳

请教SQL查询语句 学生选课问题

表名:student
字段:id,name
数据如下:
1,学生A
2,学生B

3,学生C

表名:subject
字段:id,name
数据如下:
1,数学
2,物理

3,化学

表名:map_student_subject
字段:studentid, subjectid
数据如下:
1,1
1,2
1,3
2,1
2,2

3,3

现在的问题是查询出同时选择了数学,物理并且没有选择化学的学生姓名。
根据数据,期待的结果应该是:学生B

请问这个Sql应该怎么写啊?
另外我下面的这个写法哪里不对啊?也希望能够一并指出,非常感谢!
[color=blue]select student.name
from
student
join map_student_subject ma
join map_student_subject mb
join map_student_subject mc
on student.id = ma.studentid = mb.studentid = mc.studentid
where
ma.subjectid = '1'
and mb.subjectid = '2'
and mc.subjectid = '3'[/color]
[b]问题补充:[/b]
谢谢大家的热心帮助:>
polymorph大侠的写法是正解,可以得到预期的结果,非常感谢!
另外还想请教一下,如果采用别名的方法,该怎么写这个句子呢?
如果能抽出时间解答的话,不胜感激:D

我的写法最后一句打错字了,不是:
and mc.subjectid = '3'
应该是:
and mc.subjectid <> '3'
但是这样会得到:
学生A
学生A
学生B
学生B
@@

[b]问题补充:[/b]
谢谢energykey的提问:)
xxx=1 and xxx=2 这样肯定是不行的,
所以我想使用别名的方法,
比如我下面这样的写法:
select student.name
from
student
join map_student_subject ma
join map_student_subject mb
on student.id = ma.studentid = mb.studentid
where
ma.subjectid = '1'
and mb.subjectid = '2'
得到的结果是:
学生A
学生B
这个结果是符合预期的(即:同时选择数学物理两个科目同学)
所以给我感觉这样的写法似乎行得通,
但是当我再加上第三个别名表来限定化学的时候,就得不到预期结果了@@
这样的写法真的行不通吗?
[b]问题补充:[/b]
TO energykey:
这样的写法:
select name from student where id=
(select ma.studentid from map_student_subject ma where ma.subjectid=1 and studentid in
(select ma.studentid from map_student_subject ma where ma.subjectid=2 and ma.subjectid<>3)
)
会报错,
我看了一下子查询,会返回:学生A,学生B两个结果。
是不是什么地方笔误了?

[b]问题补充:[/b]
pengjiu大侠的方法也是正解,非常的感谢:D
分数我就平分给提供了可以得到预期答案的两位,再次感谢!!
同时向每一位热心的提供解答的大侠们致谢:D

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

11条回答 默认 最新

  • 关键词㏄ 2009-12-24 17:35
    已采纳

    [code="sql"]
    SELECT STUDENTNAME
    FROM (SELECT STUDENTID,
    SUM(CASE WHEN SUBJECTID = 1 THEN 1 ELSE 0 END) MATH,
    SUM(CASE WHEN SUBJECTID = 2 THEN 1 ELSE 0 END) PHYSICS,
    SUM(CASE WHEN SUBJECTID = 3 THEN 1 ELSE 0 END) CHEMISTRY
    FROM MAP_STUDENT_SUBJECT
    GROUP BY STUDENTID) A
    JOIN STUDENT B ON (A.STUDENTID = B.STUDENTID)
    WHERE A.MATH > 0
    AND A.PHYSICS > 0
    AND A.CHEMISTRY = 0
    [/code]

    点赞 评论
  • WdWheyr 2009-12-24 17:50

    试一下这个吧select mss_.studentid as func1_4_ from map_student_subject mss_ inner join subject sys_ on mss_.subjectid=sys_.subjectid where sys_.subjectid='1' and sys_.subjectid='2'

    点赞 评论
  • Ryankay 2009-12-24 18:03

    呵呵,你这个问题有意思,我想了一下,,,下班了,明天继续想~回家烧饭了。

    点赞 评论
  • fq_zxy 2009-12-24 18:13

    :lol: :cry:

    点赞 评论
  • fq_zxy 2009-12-24 18:16

    vdsgrs s g rsggg

    点赞 评论
  • CaiHuajiang 2009-12-24 18:31

    [code="sql"]select student.name
    from
    student
    join map_student_subject ma
    join map_student_subject mb
    join map_student_subject mc
    on student.id = ma.studentid = mb.studentid = mc.studentid
    where
    ma.subjectid = '1'
    and mb.subjectid = '2'
    and mc.subjectid = '3'[/code]

    这是语法问题,join后面必须紧跟上on语句。

    点赞 评论
  • cys202013 2009-12-24 18:54

    [code="java"]
    select s.name from student s where s.id=
    (select m.studentid map_student_subject
    m,subject sb where m.subjectid = sb.id and m.name in('数学','物理'));
    [/code]

    点赞 评论
  • Ryankay 2009-12-25 10:19

    1楼强悍啊,,,呵呵,好久没写SQL了,,,这种写法以前确实还没写过,主要是业务上没遇到过这样的需求。。。 :lol:

    楼主还在问什么?

    你这个问题的难点在于“同时选择”,这个同时在一行SQL里就难了,因为不可能同时xxx=1 and xxx=2这样肯定是没有结果的,我觉得只有通过子查询,而且需要临时表。

    光光join无法实现“交集”效果。

    点赞 评论
  • Ryankay 2009-12-25 10:50

    我想了条更简单的方法

    其实子查询的结果本身就是一张临时表,所以要求交集只需要两次子查询即可!

    代码如下
    [code="java"]
    select name from student where id=
    (select ma.studentid from map_student_subject ma where ma.subjectid=1 and ma.subjectid<>3 and studentid in
    (select ma.studentid from map_student_subject ma where ma.subjectid=2 and ma.subjectid<>3)
    )
    [/code]

    [quote]
    select name from student where id=
    (select ma.studentid from map_student_subject ma where ma.subjectid=1 and ma.subjectid<>3 and studentid in
    (select ma.studentid from map_student_subject ma where ma.subjectid=2 and ma.subjectid<>3)
    )
    [/quote]

    点赞 评论
  • pengjiu 2009-12-25 10:52

    [code="sql"] select student.id,student.name,s.id '数',l.id '理',h.id '化' from

    student student

    left join
    map_student_subject s on student.id=s.studentid and s.subjectid=1

    left join
    map_student_subject l on student.id=l.studentid and l.subjectid=2

    left join

    map_student_subject h on student.id=h.studentid and h.subjectid=3

    where isnull(h.id)=1 or length(h.id)<0[/code]

    条件你可以自己组合。

    点赞 评论
  • Ryankay 2009-12-25 10:56

    上面的第二次查询的时候ma.subjectid<>3是多于的,因为第一个子查询已经将选了3的人排除在外了。

    所以:

    [quote]select name from student where id=
    (select ma.studentid from map_student_subject ma where ma.subjectid=1 and studentid in
    (select ma.studentid from map_student_subject ma where ma.subjectid=2 and ma.subjectid<>3)
    )
    [/quote]
    即可。

    第一次查询where ma.subjectid=2 and ma.subjectid<>3,查出选了物理并且没有选化学的人,作用如下:
    1.排除了选化学的人。
    2.查出了选了物理的人。

    假设这个结果集为A,
    那么只要从A中再查询选了数学的人,就相当于执行了一次交集。

    这个方法的关键点是第二次子查询以studentid作为条件。

    点赞 评论

相关推荐 更多相似问题