Hiển thị giá trị không nằm trong điều kiện sql

Liên hệ QC

An.BA

Thành viên thường trực
Tham gia
15/9/18
Bài viết
223
Được thích
171
Giới tính
Nam
E có 2 bảng.
1. mã nhân viên
2. Nhóm công việc
Trong bảng nhóm công việc chứa
DT001;DT002;DT003;DT004...
Nhóm công việc này lặp lại nhiều lần của 1 mã nhân viên (sẽ chứa nhóm công việc mà mình đã thực hiện) và nhóm DT001 là 1 nhóm chính. Em muốn hiện thị ra 2 loại.
1. Hiện thị ra danh sách nhân viên đã có nhóm cv chính là DT001 mà k cần quan tâm nhóm khác (cái này e đã lamg được vì điều kiện nhomcv=DT001)
2. Hiện thị ra danh sách nhân viên chưa thực hiện được nhóm cv DT001. (Cái này e dùng điều kiện NOT IN (select manv from tbCongViec where nhomcv =DT001) nhưng cách này e thấy nó chậm và khiến ứng dụng của e quay khoảng 15s trong khi tìm trong dữ liệu trong 1000 row và show ra được 20 data thuộc điều kiện) em chưa tìm ra cách nào để lọc khác ạ. Mong mọi người giúp đỡ. Em cảm ơn
 
Phần 2 sao không thay = thành <> (hay NOT LIKE) của 1.
(1. Hiện thị ra danh sách nhân viên đã có nhóm cv chính là DT001 mà k cần quan tâm nhóm khác (cái này e đã lamg được vì điều kiện nhomcv=DT001) )
 
Điều kiện quan trọng: khi hỏi thì cố gắng viết rõ, tránh viết tắt. Đọc vấn đề đã phải vận dụng 100% não để hiểu rồi, còn dư đâu ra để đoán các từ viết tắt nữa !

Cách chính thống là dùng Where Not Exists
Select * From NhanVien NV Where Not Exists (Select 1 From CongViec CV Where CV.MaCongViec = 'DT001' And CV.MaNhanVien = NV.MaNhanVien)

Cách này tuy không chắc chạy nhanh hơn NOT IN nhưng tránh được một số lỗi bất ngờ mà NOT IN bị vướng.

Một cách khác để cải tiến là dùng Left Join và Null. Tuy nhiên cách này có cải tiến hay không còn tuỳ thuộc vào dạng của CSDL.
Select * From NhanVien NV Left Join (Select MaNhanVien From CongViec Where MaCongViec = 'DT001') CV On NV.MaNhanVien = CV.MaNhanVien Where CV.MaNhanVien Is Null
 
Lần chỉnh sửa cuối:
Where nhomcv <> DT001 hả bác
Nhưng như vậy trong nhóm công việc người ta làm được DT002 rồi thì nó vẫn hiện ra ạ.
Là sao vậy?
nghĩa là trong 1 record của field [nhomcv] có thể chứa "DT001;DT002;DT003;DT004" ???
Nếu đúng thế thì xem lại chuẩn hóa dữ liệu
 
Là sao vậy?
nghĩa là trong 1 record của field [nhomcv] có thể chứa "DT001;DT002;DT003;DT004" ???
Nếu đúng thế thì xem lại chuẩn hóa dữ liệu
Chuẩn rồi. Đại khái trong bảng công việc có chứa:
NV001 DT001
NV001 DT002
NV001 DT003
NV002 DT002
NV002 DT004
Bây giờ muốn truy vấn nhân viên nào không có DT001 thì sẽ ra NV002
 
Một cách khác để cải tiến là dùng Left Join và Null. Tuy nhiên cách này có cải tiến hay không còn tuỳ thuộc vào dạng của CSDL.
Select * From NhanVien NV Left Join (Select MaNhanVien From CongViec Where MaCongViec = 'DT001') CV On NV.MaNhanVien = CV.MaNhanVien Where CV.MaNhanVien Is Null

Em nghĩ nên thêm DISTINCT để lấy không trùng lặp mã NV theo câu lệnh này (vì NV có nhiều CV).

"SELECT DISTINCT NhanVien.MaNV FROM NhanVien NV.... " --> lấy 1 field mã NV
 
Em nghĩ nên thêm DISTINCT để lấy không trùng lặp mã NV theo câu lệnh này (vì NV có nhiều CV).

"SELECT DISTINCT NhanVien.MaNV FROM NhanVien NV.... " --> lấy 1 field mã NV
Left Join mà. Bên phải có nhiều thì nó mới ra nhiều. Bên phải không có thì nó chỉ ra 1 với bên phải là Null.
 
Chuẩn rồi. Đại khái trong bảng công việc có chứa:
NV001 DT001
NV001 DT002
NV001 DT003
NV002 DT002
NV002 DT004
Bây giờ muốn truy vấn nhân viên nào không có DT001 thì sẽ ra NV002
Vâng đúng ý em rồi ạ. Em cảm ơn ạ.
Bài đã được tự động gộp:

Điều kiện quan trọng: khi hỏi thì cố gắng viết rõ, tránh viết tắt. Đọc vấn đề đã phải vận dụng 100% não để hiểu rồi, còn dư đâu ra để đoán các từ viết tắt nữa !

Cách chính thống là dùng Where Not Exists
Select * From NhanVien NV Where Not Exists (Select 1 From CongViec CV Where CV.MaCongViec = 'DT001' And CV.MaNhanVien = NV.MaNhanVien)

Cách này tuy không chắc chạy nhanh hơn NOT IN nhưng tránh được một số lỗi bất ngờ mà NOT IN bị vướng.

Một cách khác để cải tiến là dùng Left Join và Null. Tuy nhiên cách này có cải tiến hay không còn tuỳ thuộc vào dạng của CSDL.
Select * From NhanVien NV Left Join (Select MaNhanVien From CongViec Where MaCongViec = 'DT001') CV On NV.MaNhanVien = CV.MaNhanVien Where CV.MaNhanVien Is Null
Vâng ạ. Em cảm ơn bác và rút kinh nghiệm lần sau ạ. Em cảm ơn nhiều nữa ạ.
 
Lần chỉnh sửa cuối:
Điều kiện quan trọng: khi hỏi thì cố gắng viết rõ, tránh viết tắt. Đọc vấn đề đã phải vận dụng 100% não để hiểu rồi, còn dư đâu ra để đoán các từ viết tắt nữa !

Cách chính thống là dùng Where Not Exists
Select * From NhanVien NV Where Not Exists (Select 1 From CongViec CV Where CV.MaCongViec = 'DT001' And CV.MaNhanVien = NV.MaNhanVien)

Cách này tuy không chắc chạy nhanh hơn NOT IN nhưng tránh được một số lỗi bất ngờ mà NOT IN bị vướng.

Một cách khác để cải tiến là dùng Left Join và Null. Tuy nhiên cách này có cải tiến hay không còn tuỳ thuộc vào dạng của CSDL.
Select * From NhanVien NV Left Join (Select MaNhanVien From CongViec Where MaCongViec = 'DT001') CV On NV.MaNhanVien = CV.MaNhanVien Where CV.MaNhanVien Is Null
Tiện đây bác giúp em 1 chút nữa ạ.
MaNhanVienNhomCongViecNgayHoanThanh
NV001DT001
10/05/2019​
NV001DT002
11/05/2019​
NV001DT003
12/05/2019​
NV001DT001
13/05/2019​
NV001DT002
14/05/2019​
NV001DT003
15/05/2019​
NV001DT002
16/05/2019​
NV001DT003
17/05/2019​
NV002DT001
18/05/2019​
NV002DT002
19/05/2019​
NV002DT003
20/05/2019​
NV002DT001
21/05/2019​
NV002DT001
22/05/2019​
NV002DT002
23/05/2019​
NV002DT003
24/05/2019​
NV002DT001
25/05/2019​
NV002DT002
26/05/2019​
NV002DT003
27/05/2019​
Giờ em muốn hiện thị ra nhóm công việc đã hoàn thành gần nhất theo từng mã nhân viên và từng nhóm công việc ạ.
Em cảm ơn nhiều lắm ạ.
 
Tiện đây bác giúp em 1 chút nữa ạ.
MaNhanVienNhomCongViecNgayHoanThanh
NV001DT001
10/05/2019​
NV001DT002
11/05/2019​
NV001DT003
12/05/2019​
NV001DT001
13/05/2019​
NV001DT002
14/05/2019​
NV001DT003
15/05/2019​
NV001DT002
16/05/2019​
NV001DT003
17/05/2019​
NV002DT001
18/05/2019​
NV002DT002
19/05/2019​
NV002DT003
20/05/2019​
NV002DT001
21/05/2019​
NV002DT001
22/05/2019​
NV002DT002
23/05/2019​
NV002DT003
24/05/2019​
NV002DT001
25/05/2019​
NV002DT002
26/05/2019​
NV002DT003
27/05/2019​
Giờ em muốn hiện thị ra nhóm công việc đã hoàn thành gần nhất theo từng mã nhân viên và từng nhóm công việc ạ.
Em cảm ơn nhiều lắm ạ.
Giả sử có >1 giá trị ngày hoàn thành là mới nhất (trường hợp nó hoàn thành cùng thời gian)?
 
Đây là trường hợp bài bản của phép truy vấn nội (textbook case of correlated query)

Select * From Bang B1 Where NgayHoanThanh In (Select Max(NgayHoanThanh) From Bang B2 Where B2.NhomCongViec = B1.NhomCongViec And B2.MaNhanVien = B1.MaNhanVien)
 
Giả sử có >1 giá trị ngày hoàn thành là mới nhất (trường hợp nó hoàn thành cùng thời gian)?
Em chưa hiểu ý bác lắm ạ.
Bài đã được tự động gộp:

Đây là trường hợp bài bản của phép truy vấn nội (textbook case of correlated query)

Select * From Bang B1 Where NgayHoanThanh In (Select Max(NgayHoanThanh) From Bang B2 Where B2.NhomCongViec = B1.NhomCongViec And B2.MaNhanVien = B1.MaNhanVien)
Em cảm ơn bác nhiều ạ.
 
Web KT

Bài viết mới nhất

Back
Top Bottom