Nhóm mẫu tin và gán giá trị theo nhóm có điều kiện ?

Liên hệ QC

dongtrien

Thành viên mới
Tham gia
13/12/11
Bài viết
18
Được thích
1
Trong Access mình muốn nhóm và gán dữ liệu theo điều kiện mang 2 giá trị 0 và 1 (true hoặc false) và kèm điều kiện NGAYGIAO >= #01/01/2019# and NGAYGIAO <= #31/01/2019# mình viết câu lệnh như thế nào ? dữ liệu mình để trong file excel gồm có hai sheet: original data và Result, trong đó Original data là dữ liệu gốc sheet còn lại là kết quả vấn tin mình cần, khi chạy vấn tin access, nhờ các bạn giúp đỡ vấn tin trên. http://www.mediafire.com/file/hkkw519bw2k3o9h/baitap_data2.xls/file
 
Lần chỉnh sửa cuối:
Trong Access mình muốn nhóm và gán dữ liệu theo điều kiện mang 2 giá trị 0 và 1 (true hoặc false) và kèm điều kiện NGAYGIAO >= #01/01/2019# and NGAYGIAO <= #31/01/2019# mình viết câu lệnh như thế nào ? dữ liệu mình để trong file excel gồm có hai sheet: original data và Result, trong đó Original data là dữ liệu gốc sheet còn lại là kết quả vấn tin mình cần, khi chạy vấn tin access, nhờ các bạn giúp đỡ vấn tin trên. http://www.mediafire.com/file/hkkw519bw2k3o9h/baitap_data2.xls/file
Mã:
SELECT HD, IIF(NGAYGIAO >= #2019/1/1# and NGAYGIAO <= #2019/1/31#,1,0)  AS BOOL, LOAIHD, SOLUONG, DONGIA, NGAYGIAO
FROM [Original data];
 
cho ra kết quả sai hết tất cả trường BOOL = 1
 
bạn chưa xem dữ liệu kết quả rồi điều kiện để đặt = 1 trong trường BOOL là LOAIHD = 'FBAN' và cùng số hợp đồng và trong tháng 1 ngược lai kết quả = 0 không tìm thấy FBAN trong tháng và nhóm hd điều mang kết quả = 0, đây là điều kiện để đặt giá trị 0 và 1, theo mình phải sử dụng subquery có truy vấn lồng nhau nhưng mình chưa nghĩ ra cách viết.
 
bạn chưa xem dữ liệu kết quả rồi điều kiện để đặt = 1 trong trường BOOL là LOAIHD = 'FBAN' và cùng số hợp đồng và trong tháng 1 ngược lai kết quả = 0 không tìm thấy FBAN trong tháng và nhóm hd điều mang kết quả = 0, đây là điều kiện để đặt giá trị 0 và 1, theo mình phải sử dụng subquery có truy vấn lồng nhau nhưng mình chưa nghĩ ra cách viết.
Bạn phải nói rỏ điều kiện ngay từ đầu
Mã:
SELECT HD, IIf(NGAYGIAO>=#1/1/2019# And NGAYGIAO<=#1/31/2019# And HD IN(SELECT HD
FROM [Original data] where LOAIHD="FBAN"),1,0) AS BOOL, LOAIHD, SOLUONG, DONGIA, NGAYGIAO
FROM [Original data];
 
Bạn phải nói rỏ điều kiện ngay từ đầu
Mã:
SELECT HD, IIf(NGAYGIAO>=#1/1/2019# And NGAYGIAO<=#1/31/2019# And HD IN(SELECT HD
FROM [Original data] where LOAIHD="FBAN"),1,0) AS BOOL, LOAIHD, SOLUONG, DONGIA, NGAYGIAO
FROM [Original data];

Subquery :
SELECT HD FROM [Original data] where LOAIHD="FBAN"

FullQuery:
dùng right outer join bảng chính với subquery. Xét nếu cái HD bên subquery là Null thì là không có.

Tổng quát:
muốn lượt ngày nằm trong tháng thì dùng Format(NgayGiao, "yyyymm") = "201901"
Dùng NGAYGIAO<=#1/31/2019# khá nguy hiểm nếu ngày ấy có chứa giờ. Thường thì người ta dùng hàm để chắc ăn là nó không chứa giờ, hoặc dùng biểu thức NGAYGIAO< #2/1/2019#
Chung chung thì nếu phải dùng ngày, nên viết theo dạng #yyyy/mm/dd# thì sẽ tránh được sự rắc rối về định dạng ngày của hệ thống.
 
Subquery :
SELECT HD FROM [Original data] where LOAIHD="FBAN"

FullQuery:
dùng right outer join bảng chính với subquery. Xét nếu cái HD bên subquery là Null thì là không có.

Tổng quát:
muốn lượt ngày nằm trong tháng thì dùng Format(NgayGiao, "yyyymm") = "201901"
Dùng NGAYGIAO<=#1/31/2019# khá nguy hiểm nếu ngày ấy có chứa giờ. Thường thì người ta dùng hàm để chắc ăn là nó không chứa giờ, hoặc dùng biểu thức NGAYGIAO< #2/1/2019#
Chung chung thì nếu phải dùng ngày, nên viết theo dạng #yyyy/mm/dd# thì sẽ tránh được sự rắc rối về định dạng ngày của hệ thống.
Dùng hàm Format quá hay, trước đây ít dùng các hàm thông thường chỉ dùng các hàm dạng Sum, Count ...
Dùng Join phải dựa vào Khóa chính, các trường sử dụng không có trường nào có thuộc tính khóa, mình không rỏ outer join là gì bạn giải thích để biết thêm
Chúc bạn 1 tối vui
 
Dùng hàm Format quá hay, trước đây ít dùng các hàm thông thường chỉ dùng các hàm dạng Sum, Count ...
Dùng Join phải dựa vào Khóa chính, các trường sử dụng không có trường nào có thuộc tính khóa, mình không rỏ outer join là gì bạn giải thích để biết thêm
Chúc bạn 1 tối vui

Lý thuyết "khóa" chỉ là ... lý thuyết. Trên thực tế, hễ có dạng "match" thì có thể join được.
Trong query của bạn, từ khóa IN tượng trưng cho VLookup/Lookup/Match

Inner Join bắt buộc A phải match với B mới cho nối thành A-B
Left Outer Join (ở trên tôi nhầm là right) lấy tất cả các phần tử A, cái nào match được với B thì nối vào thành A-B, cái nào không match được thì thành A-Null (A là bên trái, B là bên phải, Right Join thì ngược lại, lấy tất cả B)

Như vậy, nếu tôi Left Join xong thì chỉ cần xét vế thứ hai, nếu khác Null là có match (tương đương với IN), nếu Null là không có match (tương đương với NOT IN)
 
Lý thuyết "khóa" chỉ là ... lý thuyết. Trên thực tế, hễ có dạng "match" thì có thể join được.
Trong query của bạn, từ khóa IN tượng trưng cho VLookup/Lookup/Match

Inner Join bắt buộc A phải match với B mới cho nối thành A-B
Left Outer Join (ở trên tôi nhầm là right) lấy tất cả các phần tử A, cái nào match được với B thì nối vào thành A-B, cái nào không match được thì thành A-Null (A là bên trái, B là bên phải, Right Join thì ngược lại, lấy tất cả B)

Như vậy, nếu tôi Left Join xong thì chỉ cần xét vế thứ hai, nếu khác Null là có match (tương đương với IN), nếu Null là không có match (tương đương với NOT IN)
Không hình dung được cách làm, bạn dùng file của mình viết SQL cho mình và các bạn khác tìm hiểu thêm
Khuya rồi, chúc bạn ngủ ngon
 

File đính kèm

  • Database1.rar
    18.7 KB · Đọc: 9
Chỉnh code ở bài #6:

SELECT Q1.HD, IIf(Format(Q1.NGAYGIAO, "yyyymm") = "201901" And Q2.HD Is Not Null, 1, 0) As BOOL
, Q1.LOAIHD, Q1.SOLUONG, Q1.DONGIA, Q1.NGAYGIAO
FROM [Original data] Q1
Left Outer Join (Select * From [Original data] Where LOAIHD="FBAN") Q2
On Q1.HD = Q2.HD

Chỉnh lại lần nữa cho đúng với cách thường dùng của Join:

SELECT Q1.HD, IIf(Format(Q1.NGAYGIAO, "yyyymm") = "201901" And Q2.HD Is Not Null, 1, 0) As BOOL
, Q1.LOAIHD, Q1.SOLUONG, Q1.DONGIA, Q1.NGAYGIAO
FROM [Original data] Q1
Left Outer Join [Original data] Q2
On (Q1.HD = Q2.HD And Q2.LOAIHD="FBAN")

Chú: tôi chỉ nhìn code của bạn và chỉnh nó. Yêu cầu của thớt tôi khong quan tâm, vì tôi cũng chả hiểu thớt muốn gì.

Kết: join là phép tính căn bản của CSDL LH. Hầu như tất cả các CSDL LH đều có thuật toán tính phép join rất hiệu quả. Vì vậy, ở hầu hết các trường hợp, Left Join sẽ nhanh hơn phép xét IN nhiều.
 
Lần chỉnh sửa cuối:
Chỉnh code ở bài #6:

SELECT Q1.HD, IIf(Format(Q1.NGAYGIAO, "yyyymm") = "201901" And Q2.HD Is Not Null, 1, 0) As BOOL
, Q1.LOAIHD, Q1.SOLUONG, Q1.DONGIA, Q1.NGAYGIAO
FROM [Original data] Q1
Left Outer Join (Select * From [Original data] Where LOAIHD="FBAN") Q2
On Q1.HD = Q2.HD

Chỉnh lại lần nữa cho đúng với cách thường dùng của Join:

SELECT Q1.HD, IIf(Format(Q1.NGAYGIAO, "yyyymm") = "201901" And Q2.HD Is Not Null, 1, 0) As BOOL
, Q1.LOAIHD, Q1.SOLUONG, Q1.DONGIA, Q1.NGAYGIAO
FROM [Original data] Q1
Left Outer Join [Original data] Q2
On (Q1.HD = Q2.HD And Q2.LOAIHD="FBAN")

Chú: tôi chỉ nhìn code của bạn và chỉnh nó. Yêu cầu của thớt tôi khong quan tâm, vì tôi cũng chả hiểu thớt muốn gì.

Kết: join là phép tính căn bản của CSDL LH. Hầu như tất cả các CSDL LH đều có thuật toán tính phép join rất hiệu quả. Vì vậy, ở hầu hết các trường hợp, Left Join sẽ nhanh hơn phép xét IN nhiều.
Cách dùng Join của bạn quá hay, theo hướng nầy giải quyết được nhiều bài toán phức tạp
Chúc bạn vui cả ngày
 
Ví dụ rõ ràng hơn cho các bạn chưa hiểu lắm về phép join:

Mã:
Bang1                     Bang2
trg1   trg2    trg3       trg1   trg2
123    ToTe    abc        111    def
125    TeTi    def        222    xyz
212    TeTo    hij        333    hij
255    Tung    pop        444    bca
377    Xeng    bca

Select Bang1.*, Bang2.* From Bang1 Inner Join Bang2 On Bang1.trg3 = Bang2.trg2
KQ:
trg1   trg2    trg3   trg1   trg2
125    TeTi    def    111    def
212    TeTo    hij    333    hij
377    Xeng    bca    444    bca

Select Bang1.*, Bang2.* From Bang1 Left Join Bang2 On Bang1.trg3 = Bang2.trg2
KQ:
trg1   trg2    trg3   trg1   trg2
123    ToTe    abc    Null   Null
125    TeTi    def    111    def
212    TeTo    hij    333    hij
255    Tung    pop    Null   Null
377    Xeng    bca    444    bca

Chú thích: tôi cố tình đặt tên trường trệch 1 số (trg3 trong Bang1 và trg2 trong Bang2) để cho thấy phép join không hề đòi hỏi trường nào phải được đặt là khoá cả.
Ý niệm "khoá ngoại, khoá nội" trong trường hợp này chỉ là hiểu ngầm.
 
1. Không phải không quan tâm mình bận tí việc mình còn nhiều câu hỏi khó về vấn tin trên access mình đang gặp phải khi rãnh mình sẽ đưa lên, giờ rãnh mình sẽ trao đổi với các bạn, đoạn code của bạn HieuCD này chạy trên máy vẫn còn vài chổ sai mình đang tìm nguyên nhân có lẽ do mình trích 1 phần dữ liệu ra gửi diễn đàn và bớt đi điều kiện cho dể hình dung kết quả cần lấy hoặc mình đang sử dụng phiên bản access 2003 thấp hơn các bạn đã gửi file cho mình (do cty đang sử dụng phiên bản access 2003 nếu nâng lên phiên bản mới phải điều chỉnh code lại nhiều lắm nên mình phải theo).
Mã:
SELECT HD, IIf(NGAYGIAO>=#1/1/2019# And NGAYGIAO<=#1/31/2019# And HD IN(SELECT HD
FROM [Original data] where LOAIHD="FBAN"),1,0) AS BOOL, LOAIHD, SOLUONG, DONGIA, NGAYGIAO
FROM [Original data];

2. bạn HieuCD có gửi Database1.rar mình chạy file này cho kết quả đúng nhưng áp code vào chương trình vẫn còn vài chổ không đúng khi gán giá trị 0 và 1, thứ 2 mình cần là lấy theo ngày có dạng #dd/MM/yyyy# hoặc #yyyy/MM/dd# hoặc #MM/dd/yyyy# vì mình cần lấy báo cáo theo ngày, theo tuần hoặc theo tháng nên trường hợp #yyyy/MM# không phù hợp với mình, nếu mình tìm không ra lỗi mình sẽ trích xuất dữ liệu lại với điều kiện nhiều hơn.

3. dữ liệu mình chỉ nằm trên 1 Table duy nhất nên trường hợp này các bạn sử dụng Left Join , Right Join,... cho 2 Table này mình nghĩ sẽ không đụng đến. trong trường hợp dữ liệu nằm ở nhiều Table mình sẽ hỏi.
 
1. Không phải không quan tâm mình bận tí việc mình còn nhiều câu hỏi khó về vấn tin trên access mình đang gặp phải khi rãnh mình sẽ đưa lên, giờ rãnh mình sẽ trao đổi với các bạn, đoạn code của bạn HieuCD này chạy trên máy vẫn còn vài chổ sai mình đang tìm nguyên nhân có lẽ do mình trích 1 phần dữ liệu ra gửi diễn đàn và bớt đi điều kiện cho dể hình dung kết quả cần lấy hoặc mình đang sử dụng phiên bản access 2003 thấp hơn các bạn đã gửi file cho mình (do cty đang sử dụng phiên bản access 2003 nếu nâng lên phiên bản mới phải điều chỉnh code lại nhiều lắm nên mình phải theo).
Mã:
SELECT HD, IIf(NGAYGIAO>=#1/1/2019# And NGAYGIAO<=#1/31/2019# And HD IN(SELECT HD
FROM [Original data] where LOAIHD="FBAN"),1,0) AS BOOL, LOAIHD, SOLUONG, DONGIA, NGAYGIAO
FROM [Original data];

2. bạn HieuCD có gửi Database1.rar mình chạy file này cho kết quả đúng nhưng áp code vào chương trình vẫn còn vài chổ không đúng khi gán giá trị 0 và 1, thứ 2 mình cần là lấy theo ngày có dạng #dd/MM/yyyy# hoặc #yyyy/MM/dd# hoặc #MM/dd/yyyy# vì mình cần lấy báo cáo theo ngày, theo tuần hoặc theo tháng nên trường hợp #yyyy/MM# không phù hợp với mình, nếu mình tìm không ra lỗi mình sẽ trích xuất dữ liệu lại với điều kiện nhiều hơn.

3. dữ liệu mình chỉ nằm trên 1 Table duy nhất nên trường hợp này các bạn sử dụng Left Join , Right Join,... cho 2 Table này mình nghĩ sẽ không đụng đến. trong trường hợp dữ liệu nằm ở nhiều Table mình sẽ hỏi.
Các SQL trên là dạng cơ bản chạy được trên các phiên bản khác nhau
Kết quả lệ thuộc vào điều kiện xét và dữ liệu thực tế, không có file thực không thể biết "vài chổ không đúng" là do cái gì
 
Mình cũng tìm ra nguyên nhân rồi bạn, điều kiện lấy NGAYGIAO trong tháng phải nằm cùng với điều kiện FBAN

Mã:
câu lệnh này của bạn
IIf(((HDBAN.NGAYGIAO)>=#1/1/2019# And (HDBAN.NGAYGIAO)<=#1/31/2019#)) AND HD In (SELECT HD FROM HDBAN where LOAIHD='FBAN',1) AS BOOL

phải sửa câu lệnh của bạn thành
IIf(HD In (SELECT HD FROM HDBAN where LOAIHD='FBAN' AND ((HDBAN.NGAYGIAO)>=#1/1/2019# And (HDBAN.NGAYGIAO)<=#1/31/2019#)),1) AS BOOL


bạn xem code ở dưới vấn đề thứ 2 mình gặp phải NGAYGIAO xuất hiện 2 lần mình giảm bớt câu lệnh trùng lặp này:
((HDBAN.NGAYGIAO)>=#1/1/2019# And (HDBAN.NGAYGIAO)<=#1/31/2019#))
Mã:
SELECT HDBAN.HD, IIf(HD In (SELECT HD FROM HDBAN where LOAIHD='FBAN' AND ((HDBAN.NGAYGIAO)>=#1/1/2019# And (HDBAN.NGAYGIAO)<=#1/31/2019#)),1) AS BOOL, HDBAN.LOAIHD, HDBAN.SOLUONG, HDBAN.DONGIA, HDBAN.NGAYGIAO, HDBAN.CHINHANH
FROM HDBAN
WHERE (((HDBAN.NGAYGIAO)>=#1/1/2019# And (HDBAN.NGAYGIAO)<=#1/31/2019#));

theo bạn có giảm câu lệnh NGAYGIAO trên được không ?
 
Các SQL trên là dạng cơ bản chạy được trên các phiên bản khác nhau
Kết quả lệ thuộc vào điều kiện xét và dữ liệu thực tế, không có file thực không thể biết "vài chổ không đúng" là do cái gì
Phiên bản SQL:
Hàm IIF là hàm của Access, mọi đời từ 1997.
Khi nào qua TSQL hay mySQL mới cần sửa, với Access thì không cần phải lý luận thêm.

Dữ liệu thực tế:
Join là join, như tôi đã nói ở trên, trường hợp này dựa trên ý tưởng của match (*), khi bạn match, đâu có cần phải hai sheet khác nhau. Vậy thì không có lý do gì mà 1 bảng tự join nó không được.
Lập luận trong câu 3. trong bài #14 của thớt là hoàn toàn sai lầm; mức hiểu biết về CSDL LH chưa đạt căn bản.

(*) thực ra CSDL LH (Relational Database) dựa trên lý thuyết tập hợp (Set Theory). Inner Join là phép giao (intersect) giữa hai tập hợp.
 
Tổng quát:
muốn lượt ngày nằm trong tháng thì dùng Format(NgayGiao, "yyyymm") = "201901"
Dùng NGAYGIAO<=#1/31/2019# khá nguy hiểm nếu ngày ấy có chứa giờ. Thường thì người ta dùng hàm để chắc ăn là nó không chứa giờ, hoặc dùng biểu thức NGAYGIAO< #2/1/2019#
Chung chung thì nếu phải dùng ngày, nên viết theo dạng #yyyy/mm/dd# thì sẽ tránh được sự rắc rối về định dạng ngày của hệ thống.

Vụ ngày + giờ anh VietMini nói rất đúng mà nhiều người ít để ý đến chi tiết này. Không biết bên Excel như thế nào chứ bên Access là dễ đau đầu với các truy vấn liên quan đến dữ liệu dạng Date.
Vì chủ thớt đang thiết kế bên Access nên cũng góp ý thêm về dữ liệu dạng Date/Time bên Access.
- Access có kiểu dữ liệu dạng "Date/Time" và khi chọn Format: kiểu ShortDate nhưng không phải Access chỉ lưu "Ngày/tháng/năm" mà nó luôn luôn (mặc định) lưu có thêm giờ/ phút giây đi theo nó nhưng hiển thị thì chỉ "ngày/tháng/năm". Vd: 2019-03-28 12:52:05. Do đó nếu dữ liệu cột [Ngày] của bạn tổng hợp từ code VBA lấy từ hàm Now() hoặc từ nguồn dữ liệu khác (như máy chấm công, luôn có kèm giờ phút) v.v.. sẽ dễ dẫn đến dữ liệu truy vấn trả về có thể phát sinh sai sót.
Ví dụ: dữ liệu chấm công: "28/03/2018 8:05:10" --> nếu bạn truy vấn ngày #28/03/2019# nó sẽ không trả về kết quả vì ngày bạn đang truy vấn là: #28/03/2019 00:00:00# --> nếu truy vấn: [Ngay] >=#28/03/2019# And [Ngay] <#29/03/2019# thì sẽ ra kết quả.
- Dữ liệu ngày gõ tay hoặc lấy từ hàm Date() sẽ cho giờ phút giây là 00:00:00.
- Vấn đề nữa là Access chỉ nhận dạng đúng ngày tháng kiểu Mỹ - #mm/dd/yyyy# hoặc theo chuẩn quốc tế như anh VietMini có để cập là #yyyy-mm-dd#. Do đó khi truy vấn hoặc xử lý trong code VBA, bạn nên dùng hàm Format() chuyển về 1 trong 2 dạng trên để Access xử lý đúng, tốt nhất là kiểu quốc tế #yyyy-mm-dd#. Còn bạn muốn hiển thị trên Form, Report thì cứ dùng hàm Format() chuyển về kiểu #dd/mm/yyyy# cho dễ nhìn thôi.
- Có thể dùng BETWEEN #yyyy-mm-dd# AND #yyyy-mm-dd# thay cho >= và <= để gọn hơn chút. Tôi chưa thấy sai số giữa 2 cách dùng này.


Nói về ứng dụng của Sub query của chính nó rất hay và áp dụng cho nhiều trường hợp trong thực tế.
Cụ thể là: tìm giá trị của một dòng trước nó, tìm có điều kiện v.v..
Các ví dụ tôi áp dụng như:
- Tính giá số điện tiêu thụ tháng trước sau khi ghi điện, tính số km xe chạy được.
- Tính N-X-T
Ví dụ: một cách tính NXT đơn giản với subquery



Mã:
SELECT NgayPS, MaHang,Nz((
SELECT Nz(Sum(Nhap)) - Nz(Sum(Xuat))
FROM tblNX AS Prev
WHERE (((Prev.NgayPS) < tblNX.NgayPS))
GROUP BY tblNX.NgayPS 
))  AS TonDau, Nhap, Xuat, Nz(TonDau)+Nz(Nhap)-Nz(Xuat) AS TonCuoi
FROM tblNX;
 
Lần chỉnh sửa cuối:
Mình cũng tìm ra nguyên nhân rồi bạn, điều kiện lấy NGAYGIAO trong tháng phải nằm cùng với điều kiện FBAN

Mã:
câu lệnh này của bạn
IIf(((HDBAN.NGAYGIAO)>=#1/1/2019# And (HDBAN.NGAYGIAO)<=#1/31/2019#)) AND HD In (SELECT HD FROM HDBAN where LOAIHD='FBAN',1) AS BOOL

phải sửa câu lệnh của bạn thành
IIf(HD In (SELECT HD FROM HDBAN where LOAIHD='FBAN' AND ((HDBAN.NGAYGIAO)>=#1/1/2019# And (HDBAN.NGAYGIAO)<=#1/31/2019#)),1) AS BOOL


bạn xem code ở dưới vấn đề thứ 2 mình gặp phải NGAYGIAO xuất hiện 2 lần mình giảm bớt câu lệnh trùng lặp này:
((HDBAN.NGAYGIAO)>=#1/1/2019# And (HDBAN.NGAYGIAO)<=#1/31/2019#))
Mã:
SELECT HDBAN.HD, IIf(HD In (SELECT HD FROM HDBAN where LOAIHD='FBAN' AND ((HDBAN.NGAYGIAO)>=#1/1/2019# And (HDBAN.NGAYGIAO)<=#1/31/2019#)),1) AS BOOL, HDBAN.LOAIHD, HDBAN.SOLUONG, HDBAN.DONGIA, HDBAN.NGAYGIAO, HDBAN.CHINHANH
FROM HDBAN
WHERE (((HDBAN.NGAYGIAO)>=#1/1/2019# And (HDBAN.NGAYGIAO)<=#1/31/2019#));

theo bạn có giảm câu lệnh NGAYGIAO trên được không ?
Ngày tháng bạn nên chuyển thành dạng #yyyy/mm/dd# chuẩn hơn
Điều kiện xét truy vấn của mình và của bạn khác nhau nên kết quả khác nhau vì 1 HD có nhiều ngày giao
Truy vấn thứ 2 không rút gọn điều kiện NGAYGIAO được vì vai trò của 2 điều kiện khác nhau theo điều kiện của bạn, nếu theo điều kiện của mình thì bỏ được trong subquery
 
...
- Có thể dùng BETWEEN #yyyy-mm-dd# AND #yyyy-mm-dd# thay cho >= và <= để gọn hơn chút. Tôi chưa thấy sai số giữa 2 cách dùng này.

BETWEEN đúng là tiêu chuẩn SQL. Tất nhiên là dùng nó sẽ gọn hơn. Và nó chính là cách nên dùng.

Chú thích:
Toán tử BETWEEN chỉ đề cập đến vế trái so sánh 1 lần. Toán tử >= And <= đề cập đến vế trái 2 lần.
Nếu vế trái chỉ là một biến (variable/item) hay trường (field) thì cách hoạt động in hệt nhau. Trên thực tế, các phần mềm có tối ưu hoá sẽ tự chỉnh quy trình vận hành (execution plan) ra in hệt nhau.
Tuy nhiên, nếu vế trái là một biểu thức hoặc hàm (phải tính toán) thì BETWEEN chỉ tính 1 lần trong khi loại so sánh >=&<= kia phải tính biểu thức 2 lần.
FuncA(abc) BETWEEN x AND y
FuncA(abc) >= x AND FuncA(abc) <= y
Trường hợp này, chọn lựa cách nào là do nhu cầu chạy hàm 1 hay 2 lần chứ không phải do cái nào gọn hơn.

...Truy vấn thứ 2 không rút gọn điều kiện NGAYGIAO được vì vai trò của 2 điều kiện khác nhau theo điều kiện của bạn, nếu theo điều kiện của mình thì bỏ được trong subquery
Cách làm của thớt trong bài #16 là truy vấn liên hệ nội (correlated). Câu lệnh không tương đương. Nó là truy vấn khác, không phải là rút gọn.
 
Lần chỉnh sửa cuối:
Web KT
Back
Top Bottom