MySQL嵌套查询问题和优化

时间:2015-12-17 23:08:05

标签: mysql sql

我有科学会议数据库。

  • Conferencis在Universitis举行
  • 每个学生都可以参加任何会议。
  • 每所大学都有很少的学生
CREATE TABLE uni #University
(
  region          varchar(255) NOT NULL,
  name            varchar(255) NOT NULL,
  id              int unsigned NOT NULL auto_increment,     
  PRIMARY KEY     (id)
);

CREATE TABLE student 
(
    uni_id          int unsigned NOT NULL,
    name            varchar(255) NOT NULL,
    id              int unsigned NOT NULL auto_increment,
    PRIMARY KEY     (id),
    FOREIGN KEY (uni_id) REFERENCES uni (id)
);

CREATE TABLE conf #Conference
(
    uni_id          int unsigned NOT NULL,
    name            varchar(255) NOT NULL, 
    id              int unsigned NOT NULL auto_increment,
    PRIMARY KEY     (id),
    FOREIGN KEY     (uni_id) REFERENCES uni (id)
);


CREATE TABLE visits #table participants
# id_student visit conference id_conf and maybe have winnner place
(
    id_conf         int unsigned NOT NULL, 
    id_student      int unsigned NOT NULL,
    place           int unsigned, #1..3
    PRIMARY KEY     (id_conf, id_student),

    FOREIGN KEY (id_conf) REFERENCES conf (id),
    FOREIGN KEY (id_student) REFERENCES student (id)
);

我需要代码5选择请求:

1)获取访问会议“DataBase 2015”

的学生的姓名
SELECT vc.name FROM
    (SELECT * FROM visits v 
        INNER JOIN conf c 
        ON (v.id_conf = c.id)) vc # visits with names of conference
    INNER JOIN student s 
    ON (vc.id_student = s.id)
    WHERE vc.name = "DataBase 2015";

2)获得学生在会议“数据库2015”

上获奖者的不利之处
SELECT DISTINCT uni_id 
    FROM student s 
    INNER JOIN 
          (SELECT id_student 
                  FROM visits v 
                  INNER JOIN conf c 
                  ON (v.id_conf = c.id) 
                  WHERE (v.place is NOT NULL and 
                         c.name = "DataBase 2015")
           ) winers
    ON (winers.id = i.id_student);

3)获得大学ID,举办超过1次会议

SELECT uni_id FROM conf c GROUP BY c.uni_id having COUNT(*) > 1;

4)获得大学哪个学生在所有会议中都有位置。 这意味着我们需要比较所有会议的数量和一些大学的学生有哪些胜利的会议数量

需要写这样的东西(java):

uni_list.stream().filter( uni -> {
        Set<Conference> id_have_winners = new new HashSet<>;
        for(Student s : getStudents(uni.getId()) {
            for(Conference c : conferences) {
               if (studentWinConference(s, c)
                   id_have_winners.put(c);
        }
        bool haveWinnersInAllConferences = id_have_winners.size() == conferences.size();
        return haveWinnersInAllConferences;
}

5)获取Uni,学生只访问一个会议。

SELECT id_conf, id_student, uni_id FROM 
    visits v INNER JOIN student s ON (s.id = v.id_student) GROUP BY s.uni_id having COUNT(v.id_conf) = 1

6)获得Uni哪些学生参加了一些会议,但没有人获胜

1,2,3是有效的,但我需要сouncil以便进行简化; 4,5,6很难,我很乐意提供任何提示或代码

1 个答案:

答案 0 :(得分:1)

尝试这些查询。我们欢迎您向http://sqlfiddle.com/#!9/12247/16示例添加一些数据,如果有什么不起作用,请告诉我。也包括预期的产出。

访问会议的学生姓名“DataBase 2015”

select distinct s.name
from visits v
inner join conf c on v.id_conf = c.id
inner join student s on v.id_student = s.id
where c.name = 'DataBase 2015'

获得“DataBase 2015”学生的大学ID

select distinct u.id
from visits v
inner join conf c on v.id_conf = c.id
inner join student s on v.id_student = s.id
inner join uni u on s.uni_id = u.id
where place is not null
and c.name = 'Database 2015'

举办过1次以上会议的大学ID

select uni_id
from conf
group by uni_id
having count(*) > 1

大学与学生一起参加所有会议

select distinct s.uni_id
from student s
left join (
  select id_conf, id_student, uni_id
  from visits v 
  inner join conf c on v.id_conf = c.id
  where place is not null
) data on data.id_student = s.id and data.uni_id = s.uni_id
where data.id_student is not null

大学生只参加了一次会议

select s.uni_id
from visits v
inner join conf c on v.id_conf = c.id
inner join student s on v.id_student = s.id
group by s.uni_id
having count(*) = 1

未安排学生的大学

select distinct s.uni_id
from student s
left join (
  select id_conf, id_student, uni_id
  from visits v 
  inner join conf c on v.id_conf = c.id
  where place is null
) data on data.id_student = s.id and data.uni_id = s.uni_id
where data.id_student is not null