• Vui lòng đọc nội qui diễn đàn để tránh bị xóa bài viết
  • Tìm kiếm trước khi đặt câu hỏi

Một số lệnh truy vấn kết hợp nhiều mệnh đề khác nhau

Các bài viết hướng dẫn, giúp các bạn hiểu và tiếp cận với Visual Basic nhanh hơn
User avatar
thuccads
Thành viên tích cực
Thành viên tích cực
Posts: 143
Joined: Mon 01/02/2010 8:35 am
Location: Hà Nội--->Sài Gòn
Been thanked: 1 time
Contact:

Một số lệnh truy vấn kết hợp nhiều mệnh đề khác nhau

Postby thuccads » Tue 27/04/2010 10:26 pm

Tên bài viết: Một số lệnh truy vấn kết hợp nhiều mệnh đề khác nhau
Tác giả: thuccads
Cấp độ bài viết: Advance
Tóm tắt: Một số lệnh truy vấn kết hợp nhiều mệnh đề khác nhau / SQL Server




Bài này tôi giới thiệu với các bạn một số lệnh truy vấn dữ liệu từ nhiều bảng khác nhau, kết hợp một số câu lệnh truy vấn SQL. Không biết đã có ai post bài tương tự chưa nhưng tôi xin mạo muội. Mọi chỉ giáo xin gửi về... :D . Tôi có đính kèm theo database và cả script.
Trong CSDL tôi có các bảng sau : LstDoituong(danh mục đối tượng), LstTaikhoan(danh mục tài khoản), PsTienmatDetails(Phát sinh chi tiết tiền).
Trong trong các bảng thì trường id tôi đặt tự tăng.
Trong bảng LstTaikhoản có trường id_tk_me. ví dụ 111 được gọi là tài khoản mẹ của 1111, vậy nếu 111 có id=1 thì id_tk_me của 1111 là 1.
Trong bảng PsTienmatDetails có các trường id_tk_no và id_tk_co liên kết với bảng LstTaikhoan qua trường id_tk. vậy nếu giả thiết trong bảng LstTaikhoan ma_tk=6278, id_tk=1; ma_tk=1111, id_tk=2 thì trong bảng PsTienmatDetails lưu : id_tk_no=1, id_tk_co=2, tien=10 000 000. OK đó là các giả thích về bảng dữ liệu, sau đây tôi sẽ giới thiệu các câu truy vấn ví dụ. (Vì tôi ngại chụp hình nên các bạn cứ download về chạy script xem kết quả nhé.
1-Mệnh đề INNER JOIN :
Phát biểu SQL dạng SELECT có sử dụng mệnh đề INNER JOIN được sử dụng để liên kết hai hay nhiều bảng với nhau, cú pháp như sau :
SELECT [f1,f2...fn]
FROM <table1>
INNER JOIN <table2>
ON <JOIN CONDITION>
...
INNER JOIN <tablen>
ON <JOIN CONDITION>

sau INNER JOIN bạn dùng các câu lệnh khác bình thường như : WHERE, GROUP BY, ORDER BY.
Ví dụ tôi muốn lấy ra các thông tin theo thứ tự từ các bảng trên : ma_tk thay cho các id_tk_no và id_tk_co trong bảng PsTienmatDetails :

Code: Select all

SELECT tkno.ma_tk as tk_no
   , tkco.ma_tk as tk_co
   , ps.tien as tien, ps.dien_giai as dien_giai
FROM LstTaikhoan tkno
   INNER JOIN PsTienmatDetails ps ON tkno.id_tk=ps.id_tk_no
   INNER JOIN LstTaikhoan tkco ON tkco.id_tk=ps.id_tk_co
ORDER BY tkno.ma_tk

Ở đây tôi đã alias bảng LstTaikhoan thành hai bảng tkno và tkco để lấy tk_no thay id_tk_no và tkco lấy tk_co thay id_tk_co. Cuối cùng ta được các thông tin là mã thay cho id.
2. Mệnh đề LEFT JOIN
Khác với mệnh đề INNER JOIN là điều kiện sau từ khóa "ON" phải tồn tại trong cả hai bảng thì LEFT JOIN sẽ lấy tất cả các thông tin của bảng bên trái mà không cần tồn tại trong bảng bên phải, cú pháp như sau :
SELECT [f1,f2...fn]
FROM <table1>
LEFT JOIN <table2>
ON <JOIN CONDITION>
...
INNER JOIN <tablen>
ON <JOIN CONDITION>
Ví dụ tôi có câu truy vấn sau :

Code: Select all

SELECT tk.ma_tk
   , ps.dien_giai, ps.tien
FROM LstTaikhoan tk
   LEFT JOIN PsTienmatDetails ps on tk.id_tk=ps.id_tk_no
order by tk.ma_tk

Kết quả là có những dòng trường ma_tk có giá trị khác NULL nhưng trường dien_giai, tien có giá trị NULL.
Một ví dụ khác : Giả thiết trong bảng LstTai khoản tôi muốn đưa ra mã tài khoản mẹ thay vì id :

Code: Select all

SELECT tk.ma_tk, tk.ten_tk,tk.bac_tk
   , CASE WHEN tk.Bac_Tk>1 THEN tkm.Ma_Tk ELSE '' END AS Ma_Tk_Me
   , CASE WHEN tk.Bac_Tk>1 THEN tkm.Ten_Tk ELSE '' END AS Ten_Tk_Me
FROM LstTaikhoan tk     
   LEFT JOIN LstTaikhoan tkm ON tkm.ID_TK=tk.ID_TK_ME

Các bạn có thể áp dụng câu truy vấn này cho các trường hợp truy vấn kết quả dạng cây không giới hạn cấp.
3.Mệnh đè RIGHT JOIN
Giống mệnh đề LEFT JOIN chỉ khác phía bảng sau từ khóa ON
4.Mệnh đề CROSS JOIN
Một lời khuyên là hạn chế dùng CROSS JOIN nếu không kiểm xoát được. nó sẽ đưa ra kết quả là cấp số nhân của bảng trước và sau mệnh đề. Ví dụ tôi viết như sau :

Code: Select all

SELECT tk.ma_tk, ps.tien, ps.dien_giai
FROM LstTaikhoan tk
   CROSS JOIN PsTienmatDetails ps

Kết quả là nếu bảng LstTaikhoan nếu có 100 dòng và bảng PsTienmatDetails có 200 dòng thì nó đưa ra kết quả là 100*200=2000 dòng :D .
Các bạn hãy thử đặt thêm điều kiện với WHERE để xem nó chạy thế nào nhé.
5.Mệnh đề UNION
Khác với các lệnh "JOIN" thì UNION liên kết các bảng bằng các câu truy vấn theo dạng hàng dọc, có thể nói là gộp dữ liệu theo hàng dọc với điều kiện : các trường trong các câu truy vấn phải bằng nhau về số lượng, đọ dài , kiểu dữ liệu.
Như các bạn thấy trong bảng PsTienmatDetails chỉ có một trường tien và hai trường lưu thông tin tài khoản. Bây giờ tôi sẽ lấy ví dụ làm ngược lại : Tính tổng phát sinh nợ (tương ứng id_tk_no), phát sinh có (tương ứng id_tk_co) của các đối tượng với điều kiện mã tài khoản bằng một tài khoản nào đó. Đây là câu lệnh kết hợp nhiều câu lệnh :

Code: Select all

SELECT ma_tk, ten_dt, SUM(ps_no) as ps_no, SUM(ps_co) as ps_co
   , CASE WHEN SUM(ps_no-ps_co)>=0 THEN ABS(SUM(ps_no-ps_co)) END as du_no_ck
   , CASE WHEN SUM(ps_no-ps_co)<0 THEN ABS(SUM(ps_no-ps_co)) END as du_co_ck
FROM
(
   SELECT tk.ma_tk
      , dt.ten_dt
      , pst.tien as ps_no, 0 as ps_co, pst.dien_giai as dien_giai
   FROM LstTaikhoan tk
      INNER JOIN PsTienmatDetails pst ON tk.id_tk=pst.id_tk_no
      INNER JOIN LstDoituong dt ON dt.id_dt=pst.id_dt
   WHERE tk.ma_tk = '331'
   UNION
   SELECT tk.ma_tk
      , dt.ten_dt
      , 0 as ps_no, pst.tien as ps_co, pst.dien_giai as dien_giai
   FROM LstTaikhoan tk
      INNER JOIN PsTienmatDetails pst ON tk.id_tk=pst.id_tk_co
      INNER JOIN LstDoituong dt ON dt.id_dt=pst.id_dt
   WHERE tk.ma_tk = '331'
) AS A
GROUP BY ma_tk, ten_dt   

Kết quả ta được: mã tài khoản, tên đối tượng, tổng phát sinh nợ, tổng phát sinh có, tổng dư có cuối kỳ, tổng dư nợ cuối kỳ.
Tạm dừng ở đây. Đáng lẽ tôi làm các bảng có nôi dung khác sẽ dễ hiểu hơn nhưng ngại quá nên lấy bảng từ CSDL của tôi. Có pác nào làm phần mềm kế toán hãy góp ý nhiều hơn nhé. :)
Attachments
pack.zip
(265.08 KiB) Downloaded 1196 times
Last edited by truongphu on Fri 21/05/2010 5:12 am, edited 1 time in total.
Reason: Thêm phần định dạng bài viết ở đầu bài



User avatar
vie87vn
Thành viên tích cực
Thành viên tích cực
Posts: 150
Joined: Sat 05/04/2008 10:15 am
Location: Quán Đôi - Củ Chi
Been thanked: 2 times
Contact:

Re: Một số lệnh truy vấn kết hợp nhiều mệnh đề khác nhau

Postby vie87vn » Thu 29/04/2010 10:20 pm

Bài của bạn rất hay, áp dụng thực tế và đây là vấn đề mình cần học hỏi đây. Tiếp tục phát huy và bài hướng dẫn nha bạn, mình rất cần những thực tế thế này.
Nhưng Cross Join và Union bạn có thể dùng 1 ví dụ nho nhỏ và sơ sở dùng 1 tí hok? Nhìn ví dụ cũng chưa hình dung ra nổi T_T
Hoàng Sa và Trường Sa là của Việt Nam.

User avatar
thuccads
Thành viên tích cực
Thành viên tích cực
Posts: 143
Joined: Mon 01/02/2010 8:35 am
Location: Hà Nội--->Sài Gòn
Been thanked: 1 time
Contact:

Re: Một số lệnh truy vấn kết hợp nhiều mệnh đề khác nhau

Postby thuccads » Thu 29/04/2010 10:26 pm

vie87vn wrote:Bài của bạn rất hay, áp dụng thực tế và đây là vấn đề mình cần học hỏi đây. Tiếp tục phát huy và bài hướng dẫn nha bạn, mình rất cần những thực tế thế này.
Nhưng Cross Join và Union bạn có thể dùng 1 ví dụ nho nhỏ và sơ sở dùng 1 tí hok? Nhìn ví dụ cũng chưa hình dung ra nổi T_T

Mình có kèm database mà bạn. Nếu bạn có trường hợp cụ thể mình sẽ post dễ hiểu hơn.

User avatar
vie87vn
Thành viên tích cực
Thành viên tích cực
Posts: 150
Joined: Sat 05/04/2008 10:15 am
Location: Quán Đôi - Củ Chi
Been thanked: 2 times
Contact:

Re: Một số lệnh truy vấn kết hợp nhiều mệnh đề khác nhau

Postby vie87vn » Tue 04/05/2010 1:47 pm

Tải về xong mới biết là... máy mình cùi bép nên không có cài SQL Server T_T
Bạn thử 1 ví dụ nho nhỏ đi :))
Mà hỏi riêng bạn tí, bạn dùng chương trình này do chính bạn thiết kế àh? Hix, mún tìm hiểu 1 phần mềm kế toán, nhưng hok có nghiệp vụ kế toán, chả tới đâu :(
Hoàng Sa và Trường Sa là của Việt Nam.

User avatar
thuccads
Thành viên tích cực
Thành viên tích cực
Posts: 143
Joined: Mon 01/02/2010 8:35 am
Location: Hà Nội--->Sài Gòn
Been thanked: 1 time
Contact:

Re: Một số lệnh truy vấn kết hợp nhiều mệnh đề khác nhau

Postby thuccads » Tue 04/05/2010 4:46 pm

vie87vn wrote:Tải về xong mới biết là... máy mình cùi bép nên không có cài SQL Server T_T
Bạn thử 1 ví dụ nho nhỏ đi :))
Mà hỏi riêng bạn tí, bạn dùng chương trình này do chính bạn thiết kế àh? Hix, mún tìm hiểu 1 phần mềm kế toán, nhưng hok có nghiệp vụ kế toán, chả tới đâu :(

Bạn thử gửi một đoạn bài mình viết vào google là biết ngay tui viết hay copy ở đâu mà :D . Bạn muốn ví dụ nho nhỏ nhưng cụ thể hơn chút. Với pm kế toán thì chắc cũng không khó khăn gì ;) (có thể thảo luận nhiều vấn đề quy mô lớn :D ) .


Return to “[VB] Bài viết hướng dẫn”

Who is online

Users browsing this forum: No registered users and 0 guests