在不使用JOIN的情况下计算每个班级的学生人数

时间:2019-06-29 02:53:24

标签: mysql sql

如果我删除了GROUP BY条件,它将尝试在MySQL工作台上运行此查询,该条件将输出包含所有班级学生总数的数据表。我需要每班的总人数,而无需使用加入,因为这是在子查询上进行训练

SELECT Class.ID,Class.Name,Class.Description,Class.Code,Class.MaximumStudents,
 (SELECT COUNT(StudentID) AS numberOfStudentinClass 
  FROM ClassStudent 
  GROUP BY CLASSID) AS NumberOFStudentPerClass 
FROM Class;

这是查询和结果的屏幕截图

Imgur

3 个答案:

答案 0 :(得分:2)

您可以尝试使用此方法,而无需使用GROUP BY

select class.name ,
       (select count(student.id) as total 
        from student
        where class.id = student.class_id
       ) as custom 
from class;

答案 1 :(得分:0)

如果您可以不使用班级名称而生活,那么您可以简单地运行它...

type Book struct {
    ID     string  `json:"id"`
    Isbn   string  `json:"isbn"`
    Title  string  `json:"title"`
    Author *Author `json:"author"`
}

//Author struct
type Author struct{
    Firstname string `json:"firstname"`
    Lastname  string `json:"lastname"`
}

//variables

//slice-> variable link to array
var books []Book



// Get single book
func getBook(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    params := mux.Vars(r) // Gets params
    // Loop through books and find one with the id from the params
    for _, item := range books {
        if item.ID == params["id"] {
            json.NewEncoder(w).Encode(item)
            return
        }
    }
    json.NewEncoder(w).Encode(&Book{})
}

func main() {
    // r := mux.NewRouter()
    fmt.Println("hello api")
    //initialize mux router
    r := mux.NewRouter()
    //mock data
    books=append(books,Book{ID:"1",Isbn:"32123",Title:"Book   one",Author:&Author{Firstname:"J.K.", Lastname:"Rowling"}})
    books=append(books,Book{ID:"2",Isbn:"45434",Title:"Book two", Author:&Author{Firstname:"P.K.",Lastname:"Rowling"}})

    //router handler
    r.HandleFunc("/api/books",getBooks).Methods("GET")
    r.HandleFunc("/api/books/{id}",getBook).Methods("GET")
    r.HandleFunc("/api/books",createBook).Methods("POST")
    r.HandleFunc("/api/books/{id}",updateBook).Methods("PUT")
    r.HandleFunc("/api/books/{id}",deleteBook).Methods("DELETE")

    log.Fatal(http.ListenAndServe(":8080",r))    
}

但是,如果您还想要类名,则只有几个选项。

  1. 加入班级上的班级表
  2. 使用相关的子查询(但这有点像联接,但没有关键字join)。您也可以使用旧的“ from子句中逗号分隔的表列表”,但这仍然涉及联接,只是没有join关键字。 或者
  3. 通过向班级学生表添加表来对班级名称进行非规范化。我不建议这样做,因此不会显示此SQL。

这是选项1。我不明白您为什么特别想要加入。毕竟,这就是联接的目的。...

也许您可以在问题上添加解释,说明为什么您不喜欢使用联接。...

无论如何,这里是选项1。

{
    "id": "1",
    "isbn": "32123",
    "title": "Book one",
    "author": {
        "firstname": "J.K.",
        "lastname": "Rowling"
    }
}

答案 2 :(得分:0)

将其表示为相关子查询是完全合理的:

SELECT c.ID, c.Name, c.Description, c.Code, c.MaximumStudents,
       (SELECT COUNT(*) 
        FROM ClassStudent cs
        WHERE cs.CLASSID = c.ID
       ) as NumberOFStudentPerClass 
FROM Class c;

注意:

  • 您的版本不起作用。除其他外,您将收到一个错误,即子查询返回了多行。
  • 即使没有行匹配,子查询也将始终仅返回一行。在这种情况下,该值为0,而不是NULL
  • 条件cs.CLASSID = c.ID相关条件,将子查询中的行与外部查询进行匹配。
  • 使用表别名。它们使查询更易于编写和阅读。
  • 无需在子查询中命名该列。您确实想在外部查询中将其命名。