bảng phụ thuộc

Bây giờ hãy làm phức tạp các truy vấn của chúng tôi một chút. Hãy thêm một bảng nhiệm vụ mới vào cơ sở dữ liệu của chúng ta với các nhiệm vụ dành cho nhân viên của chúng ta. Và hãy xem nó chứa những mục nào:

SELECT * FROM task

Kết quả của một yêu cầu như vậy:

nhận dạng nhân viên_id tên thời hạn
1 1 Sửa lỗi ở frontend 2022-06-01
2 2 Sửa lỗi trên backend 2022-06-15
3 5 Mua cà phê 2022-07-01
4 5 Mua cà phê 2022-08-01
5 5 Sẽ mua cà phê 2022-09-01
6 (VÔ GIÁ TRỊ) Dọn dẹp văn phòng (VÔ GIÁ TRỊ)
7 4 Tận hưởng cuộc sống (VÔ GIÁ TRỊ)
số 8 6 Tận hưởng cuộc sống (VÔ GIÁ TRỊ)

Bảng này chỉ có 4 cột:

  • id — số nhiệm vụ duy nhất (và các hàng trong bảng);
  • employee_id — ID của nhân viên từ bảng nhân viên được giao nhiệm vụ;
  • tên — tên và mô tả nhiệm vụ;
  • thời hạn - thời gian mà nhiệm vụ phải được hoàn thành.

Hãy chú ý đến một vài sắc thái. Nhiệm vụ N6 không có employee_id, chúng tôi không có trình dọn dẹp. Nhiệm vụ ở đó, nhưng người thực hiện thì không. Nó xảy ra.

Ngoài ra, nhiệm vụ 6-9 không có thời hạn nhất định. Điều này xảy ra khi một nhiệm vụ phải được thực hiện thường xuyên và liên tục. Ví dụ, văn phòng cần được dọn dẹp mỗi ngày, nhưng bạn cũng cần tận hưởng cuộc sống mỗi ngày :)

Nếu một bảng sử dụng ID từ một bảng khác, thì bảng đó được gọi là phụ thuộc .

Truy vấn đối với nhiều bảng

Ở đây ta thấy trong bảng nhiệm vụ có 2 nhiệm vụ “Tận hưởng cuộc sống”. Làm thế nào để chúng ta biết những người may mắn này là ai?

Để làm điều này, trong SQL, bạn có thể thực hiện một truy vấn trên hai bảng cùng một lúc. Nói chung, trong SQL, bạn có thể truy vấn bất kỳ số lượng bảng nào cùng một lúc. Định dạng chung cho một yêu cầu như vậy là:

SELECT columns
FROM Table 1, table 2, tableN

Quan trọng! Nếu bạn viết một truy vấn cho nhiều bảng cùng một lúc, thì kết quả là bạn sẽ nhận được cái gọi là tích Đề các của các hàng trong bảng. Mỗi hàng từ bảng đầu tiên sẽ được dán vào từng hàng từ bảng thứ hai, v.v.

Nghĩa là, nếu bạn có 5 hàng trong bảng đầu tiên và 10 hàng trong bảng thứ hai, thì tổng cộng bạn sẽ có 50 hàng. Trong Java, truy vấn này sẽ giống như thế này:

for (String row1 : table1)
{
	for (String row2 : table2)
   {
  	System.out.println(row1 + row2);
   }
}

Hãy viết truy vấn của chúng ta vào hai bảng cùng một lúc và xem điều gì sẽ xảy ra:

SELECT * FROM employee, task

Và kết quả của truy vấn này:

nhận dạng tên nghề nghiệp lương tuổi nhận dạng nhân viên _nhận dạng tên thời hạn
1 Ivanov Ivan lập trình viên 100000 25 1 1 Sửa lỗi ở frontend 2022-06-01
2 Petrov Petr lập trình viên 80000 23 1 1 Sửa lỗi ở frontend 2022-06-01
3 Ivanov Serge Kiểm thử 40000 ba mươi 1 1 Sửa lỗi ở frontend 2022-06-01
4 Rabinovich Moisha Giám đốc 200000 35 1 1 Sửa lỗi ở frontend 2022-06-01
5 kirienko anastasia Quản lý văn phòng 40000 25 1 1 Sửa lỗi ở frontend 2022-06-01
6 Vaska con mèo 1000 3 1 1 Sửa lỗi ở frontend 2022-06-01
1 Ivanov Ivan lập trình viên 100000 25 2 2 Sửa lỗi trên backend 2022-06-15
2 Petrov Petr lập trình viên 80000 23 2 2 Sửa lỗi trên backend 2022-06-15
3 Ivanov Serge Kiểm thử 40000 ba mươi 2 2 Sửa lỗi trên backend 2022-06-15
4 Rabinovich Moisha Giám đốc 200000 35 2 2 Sửa lỗi trên backend 2022-06-15
5 kirienko anastasia Quản lý văn phòng 40000 25 2 2 Sửa lỗi trên backend 2022-06-15

Chúng tôi có tổng cộng 48 dòng kết quả, nhưng ở đây tôi chỉ đưa ra 11 dòng. Nếu không, đơn giản là sẽ không có đủ khoảng trống.

Hãy chú ý đến ba điều:

  • Các cột có cùng tên: id . Đây là id từ bảng nhân viên và id từ bảng nhiệm vụ .
  • Các hàng của mỗi bảng được lặp lại. Ở cột bên trái, ID 6 được theo sau bởi ID = 1 một lần nữa.
  • Ví dụ, chúng tôi có các hàng vô nghĩa trong đó id (từ bảng nhân viên) là 6 và trong cùng một hàng employee_id là 1.

Loại bỏ các dòng vô nghĩa

Có quá nhiều hàng trong bảng kết quả của chúng ta, đó là tích Descartes của tất cả các hàng trong hai bảng employeetask .

Theo logic, nếu hàng employee_id là 3, thì nó chỉ nên dính vào hàng từ bảng nhân viên có id là 3. Hãy cố gắng khắc phục sự hiểu lầm này với WHERE.

Hãy viết một truy vấn như thế này:

SELECT * FROM employee, task 
WHERE emploee.id = task.emploee_id 

Và kết quả của truy vấn này:

nhận dạng tên nghề nghiệp lương tuổi nhận dạng nhân viên_id tên thời hạn
1 Ivanov Ivan lập trình viên 100000 25 1 1 Sửa lỗi ở frontend 2022-06-01
2 Petrov Petr lập trình viên 80000 23 2 2 Sửa lỗi trên backend 2022-06-15
4 Rabinovich Moisha Giám đốc 200000 35 7 4 Tận hưởng cuộc sống (VÔ GIÁ TRỊ)
5 kirienko anastasia Quản lý văn phòng 40000 25 3 5 Mua cà phê 2022-07-01
5 kirienko anastasia Quản lý văn phòng 40000 25 4 5 Mua cà phê 2022-08-01
5 kirienko anastasia Quản lý văn phòng 40000 25 5 5 Sẽ mua cà phê 2022-09-01
6 Vaska con mèo 1000 3 số 8 6 Tận hưởng cuộc sống (VÔ GIÁ TRỊ)

Tin vui là những dòng vô nghĩa đã biến mất: id từ cột đầu tiên luôn bằng employee_id.

Tin xấu là những nhiệm vụ không được giao cho bất kỳ ai, chẳng hạn như dọn dẹp văn phòng, đã biến mất. employee_id của họ là NULL, vì vậy họ đã bị loại bỏ sau khi thực hiện xong WHERE.