Hướng dẫn truy vấn trong SQL Server

Last updated: 4 years ago

Bài viết này sẽ giúp bạn nắm vững căn bản kiến thức về SQL Server để vận dụng được hầu hết trong công việc và học tập của mình. Mỗi ví dụ xem như một bài tập, bạn hãy tự thực hiện rồi đối chiếu kết quả.

Các bảng sử dụng trong các ví dụ là:

  • tblLopHoc(ID, MaLop, TenLop)
  • tblSinhVien(ID, MaSinhVien, HoDem, Ten, GioiTinh, NgaySinh, IDLopHoc)

Khởi động SQL Server Management Studio

Khởi động và đăng nhập vào SQL Server là việc dễ dàng mà bạn vẫn làm hằng ngày. Đó là vì môi trường đã được thiết lập sẵn, kết nối đến server cũng được Windows lưu lại.

Tình huống xảy ra khi bạn sử dụng máy tính không phải của mình hoặc ở một server khác trong mạng Lan, bạn sẽ lúng túng vì không connect vào được. Lúc đó bạn hãy đọc kỹ mục này.

Bạn cần biết rằng SQL Server là một service (dịch vụ) chạy nền trong Windows nên bạn sẽ tương tác với service này thông qua công cụ tích hợp sẵn gọi là SQL Server Management Studio có biểu tượng gồm một database màu vàng và công cụ thao tác.

Chưa cài SQL Server Management Studio

Nhiều bạn mở máy tính lên tìm công cụ này, không thấy và kết luận rằng chưa cài SQL Server. Thật ra chỉ là chưa cài đặt công cụ quản lý mà thôi, bạn cài đặt bổ sung vào là được. Mỗi phiên bản SQL Server sẽ có công cụ quản lý tương ứng, bạn cần chọn đúng phiên bản.

Ví dụ: bạn có SQL Server 2008 thì sẽ Google với cụm từ “SQL Server Management Studio 2008”, lập tức sẽ ra được trang download của Microsoft.


Đừng quan trọng Express hay không vì Express cũng có đầy đủ các tính năng cho bạn thao tác. Đây là công cụ miễn phí, bạn click vào link và chọn download, nếu dùng hệ điều hành 64 bit thì chọn bản x64, ngược lại thì chọn x86. Cài đặt rất dễ, cứ next hết.

Nếu xảy ra lỗi thì thường là do không đáp ứng được yêu cầu hệ thống của SQL Server, bạn kiểm tra lại xem còn thiếu cái nào, chẳng hạn cần update windows lên bản SP1, SP2 , hoặc phải update windows installer,v.v…

Đăng nhập vào SQL Server

  • Server type: Database Engine
  • Server name: tên server bạn cần kết nối, nếu nằm trên mạng Lan hoặc Wan (đã publish ra Internet), bạn sẽ nhập địa chỉ IP vào.

Ví dụ: server name = www.domain.com, server name = 192.168.1.150

Trường hợp server chạy cục bộ trên máy tính của bạn thì server name thường là (local). Nếu không biết, bạn hãy chọn “Browse for more…” trong server name thì sẽ tìm được tên server trong tab Local servers.

Đối với các server cài mới hoàn toàn, bạn cần tạo mới Database Engine trong này để nhìn thấy server name. Click chọn New database engine là được.

  • Authentication: là kiểu chứng thực. Kiểu chứng thực Window Authentication sẽ sử dụng tài khoản đăng nhập vào windows và chỉ dùng được cho server nằm trên máy tính của bạn. Ngược lại, kiểu chứng thực SQL Server Authentication để truy cập server nằm trong Mạng, nhập username và password vào là được.

Lỗi “Cannot connect to… A network-related or instance-specific error occurred while establishing a connection to SQL Server…”

Nếu server chạy local trên máy bạn, đơn giản là bật cho SQL Server service chạy. Bạn mở run (phím windows + R) , nhập “services.msc”, nếu đang stop hay pause thì bạn bật cho nó chuyển qua Started rồi đăng nhập lại.

Nếu server chạy trong mạng, trước hết hãy kiểm tra lại username và password có bị sai không. Nếu thông tin đăng nhập đã đúng rồi mà vẫn không đăng nhập được thì do lỗi ở server. Có thể do cúp điện mà service chưa chạy lại. Cũng có thể do khác lớp mạng nên không thấy được server. Lúc này, bạn cần liên hệ với người quản lý để được hỗ trợ.

Lỗi “Login failed for user…”

Lỗi xảy ra do user không có quyền truy cập , hoặc sai username, password.

Tạo Database mới

Nếu thực hiện truy vấn trên máy tính cá nhân cho mục đích học tập, bạn có thể tạo mới một cơ sơ dữ liệu. Ngược lại thì không cần vì database đã có sẵn cho bạn thao tác.

Click phải lên Database, chọn New database, nhập tên database. Nên đặt tên không dấu, không khoảng trắng. Còn lại để mặc định. Click OK.

Lệnh sql tương ứng:

create database TenDatabase

Tạo truy vấn mới

Sau khi đăng nhập thành công vào SQL Server, bạn chọn new query để bắt đầu một phiên làm việc mới, sau đó chọn đúng tên Database cần thao tác, nếu không bạn có thể vô ý làm hư dữ liệu của DB khác.

Để chọn database cần thao tác, bạn có thể chọn từ combobox hoặc dùng lệnh use:

use tên_database_cần_thao_tác

Câu lệnh Select

Về công dụng, Select cho phép bạn tìm kiếm các dòng dữ liệu thỏa mãn điều kiện nào đó. Bạn có thể gọi nó là câu lệnh select, mệnh đề select hay gì cũng được.

Cú pháp:

select cột
from bảng
  • Cột: Dùng dấu * để hiển thị tất cả các cột. Ngược lại nếu chỉ cần hiển thị một số cột thôi thì bạn liệt kê tên cột và phân cách bằng dấu phẩy. Ngoài các cột có sẵn trong bảng, câu lệnh Select cho phép bạn tạo ra cột mới được tính toán từ các cột khác.
  • Mỗi cột một dòng: Nếu phải liệt kê các cột, bạn nên liệt kê thành từng dòng, mỗi dòng một cột. Cách làm này sẽ giúp cho câu lệnh sql của bạn gọn gàng, nhìn đẹp và chuyên nghiệp. Không bị sót trong quá trình truy vấn. Đây là thói quen tốt bạn cần thực hành.

Ví dụ:

select HoDem,
       Ten,
       NgaySinh
from tblSinhVien
  • Bảng: Select cho phép bạn trích lọc dữ liệu từ một hoặc nhiều bảng, hoặc từ View và thậm chí từ kết quả của một câu Select khác.

Cách viết truy vấn Select

Viết truy vấn với Select không khó, bí quyết ở đây là bạn phải biết mình muốn tìm cái gì, bảng nào có các dữ liệu đó để mang vào Select là được.

Yêu cầu từ khách hàng, từ người quản lý thường không được rõ ràng. Thậm chí trong nhiều bài thi, bài kiểm tra, câu hỏi sẽ đánh đố bạn một chút. Lúc đó, bạn chỉ cần làm rõ là cần tìm cái gì, lấy cột nào, trong bảng nào là sẽ làm được.

Ví dụ 1: Tìm tất cả dữ liệu trong bảng tblLopHoc.
Lời giải: không nói rõ lấy cột nào nên cứ lấy hết tất cả các cột.

select *
from tblLopHoc

Ví dụ 2: Tìm tên lớp, mã lớp trong bảng tblLopHoc.
Lời giải: không lấy tất cả các cột, chỉ lấy 2 cột tên lớp và mã lớp.

select TenLop, MaLop
from tblLopHoc

Ví dụ 3: Giả sử tblSinhVien là bảng chứa dữ liệu sinh viên, gồm các cột như sau
tblSinhVien(ID, MaSinhVien, HoDem, Ten, NgaySinh, GioiTinh, IDLopHoc)
Yêu cầu: Tìm họ tên của tất cả sinh viên.
Lời giải: Nhìn vào cấu trúc của bảng, bạn sẽ thấy có 2 cột riêng biệt là HoDem và Ten. Do đó bạn sẽ kết hợp 2 cột này lại để ra được cột HoTen. Bạn có thể tạo ra một cột mới gọi là HoTenSinhVien và viết như sau:

select HoTenSinhVien = HoDem + ' ' + Ten
from tblSinhVien

Select với Top n

Top cho phép bạn lấy được n dòng ở top đầu trong kết quả trả về. Giả sử kết quả có 100 dòng, với top 5 bạn sẽ lấy 5 dòng đầu tiên trong kết quả đó.
Ứng dụng của select top khá phong phú, chẳng hạn dùng để tìm ra sinh viên có điểm cao nhất, thấp nhất, những cái lớn nhất cao nhất thì bạn sẽ dùng đến select top.

Cú pháp:

select top <số lượng> <cột>
from <bảng>

Ví dụ: tìm 5 lớp học đầu tiên trong danh sách.
select top 5 *
from tblLopHoc

Select với Order by

Kết quả trả về từ lệnh select mặc định không được sắp xếp. Khi cần sắp xếp dữ liệu, bạn sẽ dùng order by.

Cú pháp:

select cột
from bảng
order by cột_sắp_xếp [ASC|DESC]
  • Cột sắp xếp: Order by cho phép bạn sắp xếp dữ liệu theo một hoặc nhiều cột phân cách nhau bằng dấu phẩy.
  • ASC: mặc định là sắp xếp tăng dần, nên bạn có thể ghi hoặc không ghi ASC
  • DESC: sắp xếp giảm dần.

Ví dụ 1: hiển thị danh sách sinh viên, sắp xếp theo họ tên

Lời giải: ở Việt Nam, sắp xếp theo họ tên nghĩa là theo tên trước rồi mới tới họ đệm

select *
from tblSinhVien
order by Ten, HoDem

Ví dụ 2: hiển thị danh sách sinh viên, sắp xếp tăng dần theo tên, giảm dần theo họ đệm

select *
from tblSinhVien
order by Ten ASC, HoDem DESC

Select có Where

Về công dụng, mệnh đề Where sử dụng chung với câu lệnh Select để giới hạn số lượng kết quả truy vấn.

Cú pháp:

select cột
from bảng
where điều kiện
  • Điều kiện: điều kiện trong where cuối cùng phải trả về đúng sai, True/False. Do đó, trong where, bạn sẽ sử dụng các phép so sánh hoặc các toán tử trả về đúng sai như like, not like, exist, not exist. Ví dụ: Tuổi > 20, Điểm <=4.
  • Điều kiện trên từng dòng: SQL Server sẽ dùng where để tra từng dòng, cái nào không thỏa mãn thì loại bỏ.
  • Để kết hợp nhiều điều kiện với nhau, bạn sẽ dùng AND, OR, NOT,… Ví dụ: (Điểm >=8) AND (Điểm <=9)
  • Toán tử so sánh bạn có thể dùng trong where là: =, !=, <, <=, >, >=, <> Trong đó dấu = dùng so sánh bằng. Dấu != hoặc <> dùng so sánh khác.
  • So sánh với null thì dùng toán tử is. Chẳng hạn is null , is not null.
  • Đối với chuỗi thì cần đặt vào nháy đơn, không dùng nháy kép.
  • Dùng dấu ngoặc đơn để đảm bảo thứ tự thứ hiện ưu tiên trong ngoặc trước.
  • Toán tử Like: các toán tử so sánh ở trên bạn chỉ dùng cho dữ liệu số mà thôi (number), chẳng hạn 3 > 1. Đối với chuỗi (một dãy kí tự chữ), bạn nên dùng toán tử like để so sánh tương đối. Kết hợp với % sẽ cho nhiều kết quả hơn. Phủ định của like là not like.

Ví dụ: 'Nguyễn%' là chuỗi bắt đầu với Nguyễn, chẳng hạn như Nguyễn Văn A, Nguyễn Trọng Nhân, Nguyễn Cường,…

Ví dụ: '%Tuấn' là chuỗi kết thúc là Tuấn, chẳng hạn như Trần Anh Tuấn, Nguyễn Văn Tuấn, Lê Trọng Tuấn,…

Ví dụ: '%Văn%' là các chuỗi có chứa chữ Văn ở giữa, chẳng hạn Lê Văn Triều, Nguyễn Văn Bảo, Trần Văn Ơn,…

Ví dụ 1: Tìm các sinh viên họ Nguyễn

Lời giải: bảng chứa dữ liệu sinh viên là bảng tblSinhVien. Không yêu cầu lấy cột nào nên sẽ lấy hết các cột. Không lấy hết các dòng mà chỉ lấy nếu HoDem là Nguyễn.

select *
from tblSinhVien
where HoDem like N'Nguyễn%'

Giải thích

  • Kí tự N trước N'Nguyễn' là gì: vì chuỗi này là tiếng Việt, dạng ký tự Unicode. Mỗi khi có dấu thì đó là Unicode (tiếng Việt, tiếng Trung,…) bạn phải thêm N ở phía trước, không có thì SQL Server sẽ hiểu là kiểu kí tự ASCII (không dấu) nên sẽ cho kết quả sai.
  • Like: nếu bạn dùng dấu = để so sánh HoDem = N'Nguyễn' thì cũng không sai nhưng chỉ tìm được những người có Họ đệm là Nguyễn, không có tên lót. Do vậy, cứ nhớ rằng so sánh chuỗi thì dùng like là đúng nhất.

Ví dụ 2: Giả sử cột NgaySinh trong bảng tblSinhVien lưu lại ngày sinh của từng sinh viên, kiểu dữ liệu là DateTime, chẳng hạn '1995-12-25 12:00:00', là ngày 25/12/1995 lúc 12h. Yêu cầu: Tìm các sinh viên sinh năm 1995.

Lời giải: muốn biết ngày sinh thì bạn sử dụng cột NgaySinh. Vì cột này lưu theo dạng (năm-tháng-ngày giờ:phút:giây) nên bạn cần trích lọc năm ra trước, sau đó mới so sánh với 1995. Dùng hàm year() để lấy được năm từ ngày tháng ra. Không yêu cầu lấy cột nào nên cứ lấy hết.

select *
from tblSinhVien
where year(NgaySinh) = 1995

Ví dụ 3: Tương tự ví dụ trước, lần này yêu cầu “hãy tìm các sinh viên sinh năm 1995 trở về sau”
Lời giải: 1995 trở về sau nghĩa là >= 1995. Nếu người ta nói “sau 1995” thì là > 1995.

select *
from tblSinhVien
where year(NgaySinh) >= 1995

Ví dụ 4: Tìm các sinh viên có tuổi là 22.
Lời giải: cột NgaySinh sẽ cho bạn biết tuổi của sinh viên

  • Tuổi = năm hiện tại – năm sinh.
  • Năm sinh = year(NgaySinh).
  • Năm hiện tại = year(getdate()). Để lấy năm hiện tại trong SQL Server thì trước hết, dùng hàm getdate() lấy thời gian hiện tại, sau đó dùng tiếp year() để lấy năm ra.
select *
from tblSinhVien
where year(getdate()) – year(NgaySinh) = 22

Ví dụ 5: Tìm các sinh viên từ 30 tuổi trở lên.
Lời giải: tương tự ví dụ trước, lần này so sánh >= 30

select *
from tblSinhVien
where (year(getdate()) – year(NgaySinh)) >= 30

Ví dụ 6: tìm sinh viên có tên là Trọng, có họ là Trần.
Lời giải: điều kiện cần chú ý là HoDem like N'Trần%' và Ten like N'Trọng'

select *
from tblSinhVien
where HoDem like N'Trần%' AND Ten like N'Trọng'

Ví dụ 7: liệt kê tất cả sinh viên, ngoại trừ những em có họ là Lê.
Lời giải: “ngoại trừ” nghĩa là không lấy , cũng có nghĩa là chỉ lấy nếu họ đệm khác Lê. Cần chú ý là phủ định của like là not like.

select *
from tblSinhVien
where HoDem not like N'Lê%'

Between And

Ví dụ: Tìm các sinh viên có tuổi trong khoảng từ 18 đến 20.

Lời giải: nếu điều kiện so sánh có 2 mốc A, B thì bạn có thể dùng một trong 2 cách

• A <= x AND x <= B
• x between A and B. Bạn có thể sử dụng between and để so sánh trong khoảng A,B

select *
from tblSinhVien
where year(getdate()) – year(NgaySinh) >= 18
      AND year(getdate()) – year(NgaySinh) <= 20
select *
from tblSinhVien
where year(getdate()) – year(NgaySinh) between 18 and 20

Bí danh AS

Ngoài các cột có sẵn trong một bảng, Select cho phép bạn tạo ra cột mới, cột này gọi là cột tính toán vì sẽ dùng các cột có sẵn để tạo ra nó.

Ví dụ: Tìm họ đệm, tên, tuổi của sinh viên

select HoDem,
       Ten,
       TuoiSinhVien = year(getdate()) - year(NgaySinh)
from tblSinhVien

Toán tử As cho phép bạn đặt tên cho cột mới này gọi là bí danh (nickname), thậm chí cho cột hiện có của bảng.

Ví dụ:

select HoDem AS HoDemSV,
       Ten AS TenSV,
       year(getdate()) - year(NgaySinh) AS TuoiSinhVien
from tblSinhVien

Thứ tự thực hiện truy vấn

select cột
from bảng
where điều kiện
order by cột_sắp_xếp [ASC|DESC]

Theo bạn thì SQL Server sẽ thực hiện cái nào trước, có phải từ trên xuống không? Câu trả lời là không phải từ trên xuống mà theo thứ tự sau:

  • From: lấy dữ liệu từ bảng nào đó, view nào đó
  • Where: giữ lại các dòng thỏa điều kiện
  • Select: chọn ra các cột cần lấy
  • Order by: cuối cùng mới sắp xếp dữ liệu lại theo thứ tự

Truy vấn con

Truy vấn con đơn giản là các lệnh select lồng vào nhau.

Đôi khi để ra được một kết quả nào đó, bạn phải thực hiện một câu select ra một kết quả trung gian và sử dụng lại kết quả này cho câu lệnh select tiếp theo. Đó là lúc bạn sử dụng truy vấn con.

Một số lưu ý khi viết truy vấn con là:

  • Phải đặt truy vấn con vào ngoặc đơn và đặt bí danh AS nếu đặt ở From.
  • Không thể thực hiện order by trong truy vấn con được, chỉ dùng cho truy vấn cha ngoài cùng.
  • Truy vấn con sẽ được thực hiện trước truy vấn cha.
  • Truy vấn con trả về kết quả là một bảng trung gian, do đó có thể dùng ở Select, From, Where đều được.

Cú pháp:

select cột
from (truy vấn con select …) AS Bí_Danh

Bạn vẫn còn nhớ cấu trúc cơ bản của select là gì chứ?

select cột
from bảng [AS Bí_Danh]

Khi truy vấn từ một bảng thì có bí danh hay không cũng được, nhưng nếu là một truy vấn con, bạn sẽ đặt nó vào dấu ngoặc đơn và đặt cho nó một cái tên để SQL Server có thể phân biệt.

Ví dụ 1: hiển thị danh sách sinh viên, sắp xếp giảm dần theo tuổi.
Lời giải: bảng tblSinhVien chỉ có cột NgaySinh nên bạn cần phải tạo ra cột tuổi trước.

select *, TuoiSinhVien = year(getdate()) - year(NgaySinh)
from tblSinhVien

Câu lệnh này trả về 1 bảng kết quả, có tất cả các cột và có thêm một cột là tuổi sinh viên. Bạn sẽ select tiếp trên bảng kết quả trả về này, sắp xếp giảm dần theo cột tuổi.

select *
from (
     select *, TuoiSinhVien = year(getdate()) - year(NgaySinh)
     from tblSinhVien
) AS BangTrungGian
order by TuoiSinhVien DESC

Nếu bạn muốn dễ hiểu, hãy viết thành từng dòng rõ ràng giống như trên, bạn sẽ không bao giờ bị sai sót.

Ví dụ 2: tìm 10 sinh viên có tuổi cao nhất.
Lời giải: bạn còn nhớ công dụng của select top không, nó được dùng tìm những cái lớn nhất, nhỏ nhất. Trong ví dụ này là tuổi cao nhất, bạn sẽ sắp xếp giảm dần theo tuổi để tuổi cao nhất ở trên top rồi lấy 10 là xong.

select top 10 *
from (truy vấn con tính tuổi)
order by TuoiSinhVien DESC

Viết hoàn chỉnh sẽ là

select top 10 *
from (
     select *, TuoiSinhVien = year(getdate()) - year(NgaySinh)
     from tblSinhVien
) AS BangTrungGian
order by TuoiSinhVien DESC

Vị trí của truy vấn con

Truy vấn con có thể dùng ở Select, From, Where đều được nhưng bạn cần lưu ý đặc điểm của từng loại

  • From: dùng lấy dữ liệu từ một bảng, do đó truy vấn con của bạn cần trả về 1 bảng.
  • Where: điều kiện phải có tính đúng sai, true/false nên truy vấn con của bạn phải trả về true/false.
  • Select: dùng hiển thị cột, do đó, truy vấn con chỉ được trả về cột.

Ví dụ 1: tìm lớp học không có sinh viên nào. Ví dụ này sẽ minh họa cho bạn cách sử dụng truy vấn con trong where.
Lời giải:

  • Lớp học, sinh viên: bạn sẽ cần 2 bảng là tblLopHoc và tblSinhVien để giải được câu này.
  • Mỗi sinh viên thuộc 1 lớp học: tbSinhVien.IDLopHoc = tblLopHoc.ID.
  • không có sinh viên nào: bạn có thể đếm và so sánh count = 0 hoặc dùng exist. Exist trả về true nếu truy vấn con có dữ liệu, trả về false nếu truy vấn con không có dòng nào. Phủ định của exist là not exist
select *
from tblLopHoc AS lh
where not exist (truy vấn con tìm sinh viên theo lớp)

Viết hoàn chỉnh sẽ là

select *
from tblLopHoc AS lh
where not exist (
     select *
     from tblSinhVien
     where IDLopHoc = lh.ID
)

Viết tốt hơn nữa sẽ là

select *
from tblLopHoc AS lh
where not exist (
     select top 1 *
     from tblSinhVien sv
     where sv.IDLopHoc = lh.ID
)

Giải thích:

  • Đặt bí danh cho tblLopHoc là lh để bạn có thể gọi lại nó khi so sánh trong truy vấn con
    where IDLopHoc = lh.ID
  • Chỉ cần chọn được 1 sinh viên là đủ kết luận nên chỉ cần select top 1, chọn hết thì không sai nhưng chạy chậm hơn do phải lấy hết dữ liệu.
  • sv là bí danh có thể viết AS hoặc không cũng được.

Cách 2: dùng count

select *
from tblLopHoc AS lh
where (
     select count(sv.ID)
     from tblSinhVien sv
     where sv.IDLopHoc = lh.ID
) = 0

Ví dụ 2: liệt kê danh sách lớp học, hiển thị thêm số lượng sinh viên mỗi lớp. Ví dụ này sẽ minh họa cho bạn cách sử dụng truy vấn con trong select.
Lời giải:

  • Bạn cần 2 bảng là tblLopHoc và tblSinhVien để giải câu này.
  • Để đếm số lượng sinh viên, bạn sẽ dùng hàm count. Hàm count nhận vào cột, bạn đơn giản truyền cột ID của sinh viên là được. Bao nhiêu sinh viên, bấy nhiêu ID và count sẽ đếm hết.
select *, SoLuongSinhVien = (truy vấn con đếm số lượng sinh viên theo từng lớp)
from tblLopHoc AS lh

Viết hoàn chỉnh sẽ là:

select *, SoLuongSinhVien = (
     select count(sv.ID)
     from tblSinhVien sv
     where sv.IDLopHoc = lh.ID
)
from tblLopHoc AS lh

Giải thích:

• Đặt bí danh cho tblLopHoc là lh, cho tblSinhVien là sv để có thể tương tác với nhau được: sv.IDLopHoc = lh.ID. Mặc khác, lh và sv đều có cột ID, nên gọi sv.ID sẽ rõ ràng hơn là gọi ID.

Truy vấn con tương quan

Nếu bạn đã hiểu truy vấn con là gì, hiểu được các ví dụ trên thì bạn cũng đã hiểu được thế nào là truy vấn con tương quan rồi đó. Khi truy vấn con có tương tác với truy vấn cha thì gọi là tương quan. Ngược lại, truy vấn con không “đá động” gì tới truy vấn cha thì nó độc lập với cha.

SELECT với INNER JOIN

Khi cần lấy dữ liệu từ nhiều bảng, nếu các bảng này có quan hệ với nhau, bạn sẽ kết nối chung lại với nhau bằng join.

Cú pháp:

select cột
from tableA AS a
     inner join tableB AS b on điều_kiện_kết_2_bảng
  • điều_kiện_kết_2_bảng: Chẳng hạn, mỗi sinh viên thuộc 1 lớp học, do đó sinh viên và lớp học có liên quan tới nhau, thể hiện qua việc bảng sinh viên sẽ có cột IDLopHoc và hình thành được 1 điều kiện so sánh đúng sai như sau: sv.IDLopHoc = lh.ID

Trong cú pháp trên, “on” sẽ kiểm tra điều kiện đúng sai về quan hệ giữa 2 bảng. Điều kiện đúng sai thì tương tự như where, bạn cũng dùng các phép so sánh, các toán tử true/false như like, not like, exist, not exist.

  • Sử dụng AND, OR để kết nối nhiều điều kiện với nhau nếu có.

Ví dụ 1: xuất danh sách sinh viên gồm mã sinh viên, họ đệm, tên. Xuất thêm mã lớp, tên lớp của từng sinh viên đó.
Lời giải:

  • Bạn sẽ cần 2 bảng là tblSinhVien, tblLopHoc để giải câu này.
  • Điều kiện kết nối 2 bảng sẽ là sv.IDLopHoc = lh.ID
select các_cột_cần_lấy
from tblSinhVien sv
inner join tblLopHoc lh on sv.IDLopHoc = lh.ID

Viết hoàn chỉnh sẽ là:

select sv.MaSinhVien,
       sv.HoDem,
       sv.Ten,
       lh.MaLop,
       lh.TenLop
from tblSinhVien sv
inner join tblLopHoc lh on sv.IDLopHoc = lh.ID

SELECT với LEFT JOIN

Khác biệt giữ inner join và left join ở chỗ:

  • inner join: dữ liệu phải tồn tại ở 2 bảng thì mới kết được. Chẳng hạn sinh viên có IDLophoc là 10 thì bảng tblLopHoc phải có lớp ID = 10, lúc đó inner join thực hiện được và trả về kết quả. Nếu ai đó lỡ xóa mất lớp học có ID=10 thì phép kết inner join thất bại và kết quả trả về của select không có.
  • left join: giống như inner join, nhưng hay hơn ở chỗ, kết được hay không vẫn trả về kết quả, bên nào thiếu thì bên đó null.

Ví dụ 1: tìm lớp học chưa có sinh viên tham gia học.
Lời giải: các ví dụ trước đã giải bằng exist và count. Ví dụ này sẽ minh họa với left join.

select *
from tblLopHoc lh
left join tblSinhVien sv on lh.ID = sv.IDLopHoc
where sv.ID is null

Giải thích:

  • giả sử lớp học có ID = 100 là lớp học mới tạo, chưa có sinh viên nào theo học nên sẽ không có dòng nào trong bảng tblSinhVien.IDLopHoc = 100 cả.
  • Do vậy khi lấy Lớp học left join Sinh viên, thì lớp học dữ liệu còn sinh viên sẽ null. So sánh với null dùng is null.
  • Ý tưởng này thực hiện rất tốt bằng left join, nhưng inner jon thì không do inner join. Bạn tự giải thích xem như một bài tập nhé.

View là gì

Hiểu một cách “xa xỉ” thì View cho phép bạn lưu lại các câu sql mà bạn đã viết, khi cần thì select ra thôi chứ không mất công viết lại.

Công dụng của view thì có thể nói thế này, trong môi trường làm việc thực tế ở công ty, nhiều quy tắc nghiệp vụ bạn có thể không nắm được. Không sao cả, thông qua View, bạn sẽ hiểu các bảng trong DB kết nối với nhau như thế nào và từ đó sẽ hiểu được phần nào nghiệp vụ.

Cú pháp:

create view tên_view
as
truy vấn select cần lưu lại

Ví dụ: lấy lại ví dụ tìm sinh viên, liệt kê mã sinh viên, họ đệm, tên, tên lớp, mã lớp cho bạn dễ hình dung. Bạn có thể tạo một view gọi là ViewDanhSachSinhVienLopHoc như sau:

create view ViewDanhSachSinhVienLopHoc
AS
select sv.MaSinhVien,
       sv.HoDem,
       sv.Ten,
       lh.MaLop,
       lh.TenLop
from tblSinhVien sv
     inner join tblLopHoc lh on sv.IDLopHoc = lh.ID

Sau này khi cần dùng lại, bạn chỉ đơn giản select từ view ra như sau:

select *
from ViewDanhSachSinhVienLopHoc

Ví dụ: tìm danh sách sinh viên của lớp học có mã lớp là LH001.
Lời giải: tận dụng view đã viết, bạn viết rất đơn giản như sau:

select *
from ViewDanhSachSinhVienLopHoc
where MaLop = 'LH001'

Group by & Having

Group by cho phép bạn nhóm các dữ liệu lại, chẳng hạn nhóm các sinh viên cùng 1 lớp lại. Có nhiều truy vấn, đòi hỏi bạn phải nhóm lại mới thực hiện được. Đó là các truy vấn có sử dụng các hàm trong SQL Server như: count(), max(), min(), sum(), avg(). Hoặc các truy vấn bạn cần lấy tổng thể từng nhóm chứ không muốn lấy chi tiết của nhóm.

Having là điều kiện cho Group by, điều kiện này áp dụng cho cả nhóm. Nếu Select và Where là một cặp thì Group by và Having cũng là một cặp đi đôi với nhau.

Cú pháp viết đầy đủ hết sẽ là:

select các_cột_có_trong_group_by
from bảng
where điều kiện từng dòng
group by các_cột_cần_nhóm
having điều_kiện_cho_nhóm
order by cột_sắp_xếp
  • Các cột có trong group by: câu lệnh select gần nhất gắn liền với group by chỉ được select các cột dùng để group mà thôi, ngược lại sẽ bị lỗi. Ngoài ra, SQL Server cho phép bạn sử dụng các cột tính toán dùng các hàm tìm min(), max(), trung bình avg(), tính tổng sum().

Thứ tự thực hiện

Thứ tự thực hiện bây giờ khác một chút so với lần trước:

  • From: lấy dữ liệu từ bảng nào đó, view nào đó
  • Where: giữ lại các dòng thỏa điều kiện
  • Group by: nhóm các dòng lại theo tiêu chí nào đó
  • Having: giữ lại các nhóm thỏa điều kiện trong having
  • Select: chọn ra các cột cần lấy trong kết quả group
  • Order by: cuối cùng mới sắp xếp dữ liệu lại theo thứ tự

Ví dụ 1: cho biết tuổi tác trung bình của sinh viên từng lớp học.
Lời giải:

  • Bạn cần kết 2 bảng là tblLopHoc, tblSinhVien để có thể lấy được thông tin lớp học và để tính tuổi của sinh viên luôn.
  • Tuổi = year(ngày giờ hiện tại) – year(ngày sinh của sinh viên).
  • Dùng hàm avg() để tính tuổi trung bình, 
select lh.MaLop,
       lh.TenLop,
       TuoiTrungBinh = avg(year(getdate() – year(sv.NgaySinh))
from tblLopHoc lh
inner join tblSinhVien sv on lh.ID = sv.IDLopHoc
group by lh.MaLop, lh.TenLop

Ví dụ 2: cho biết ID sinh viên lớn nhất của mỗi lớp học.

select lh.MaLop,
       lh.TenLop,
       IDLonNhat = MAX(sv.ID)
from tblLopHoc lh
     inner join tblSinhVien sv on lh.ID = sv.IDLopHoc
group by lh.MaLop, lh.TenLop

Lệnh Insert

Insert cho phép bạn thêm dữ liệu vào bảng.

Cú pháp:

insert into tên_bảng(cột 1, cột 2,…)
values (giá trị cột 1, giá trị cột 2,…)

Bạn cần lưu ý thứ tự các cột và thứ tự giá trị phải tương ứng với nhau để không xảy ra lỗi. Lỗi thường gặp là sai thứ tự dẫn đến sai kiểu dữ liệu.

Ví dụ:

insert into tblSinhVien(MaSinhVien, HoDem, Ten)
values ('sv001', N'Ngô Bảo', N'Châu')

Insert kết hợp select

Bạn có thể select ra kết quả trung gian rồi insert dữ liệu với cú pháp sau:

insert into tên_bảng_A(cột 1, cột 2,…)
select cột 1, cột 2,…
from bảngB

Cú pháp này cho phép bạn lọc dữ liệu ở đâu đó và insert vào bảng bạn cần. Chỉ cần chú ý là cột của select và insert phải tương ứng về kiểu dữ liệu nếu không sẽ bị lỗi. Kiểu dữ liệu bao gồm kiểu chuỗi (char, varchar, nvarchar, text, ntext), kiểu số nguyên (int, smallint, bigint,…), kiểu số có dấu chấm thập phân (float, decimal,…)

Ví dụ:

insert into tblLopHocPhuDao(MaLop, TenLop)
select MaLop, TenLop
from tblLopHoc

Lệnh Delete

Delete cho phép bạn xóa dữ liệu của một bảng. Tốt hơn hết, trước khi xóa, bạn nên select dữ liệu ra để kiểm tra và đó sẽ là các dòng dữ liệu được xóa. Tốt hơn nữa, delete nên có where trừ khi bạn có ý định xóa sạch dữ liệu thì không cần.

Cú pháp:

delete bảng
[where điều kiện]

Ví dụ: xóa hết dữ liệu của 1 bảng

delete tblSinhVien

Ví dụ: xóa các sinh viên không có họ đệm

delete tblSinhVien
where HoDem is null

Lệnh Update

Update cho phép bạn cập nhật giá trị cho một hoặc nhiều cột, trên một hoặc nhiều bảng cùng một lúc.

Cú pháp:

update bảng
set cột = giá trị
[where điều kiện]

Điều kiện là không bắt buộc nếu bạn update toàn bộ dữ liệu của bảng. Ngược lại chỉ có các dòng thỏa điều kiện mới được cập nhật.

Ví dụ 1: cập nhật bảng lớp học, cột mã lớp thêm kí tự LH vào trước, cột tên lớp thêm chữ Lớp vào trước.
Lời giải: cập nhật bảng nhưng không có điều kiện gì thì không cần where, cập nhật hết.

update tblLopHoc
set MaLop = 'LH'+MaLop,
where TenLop = N'Lớp ' + TenLop

Ví dụ 2: cập nhật bảng sinh viên, sửa lại tên của sinh viên có mã SV005 là Huỳnh.

update tblSinhVien
set Ten = N'Huỳnh'
where MaSinhVien = 'SV005'

Lời kết

Mình viết bài này với hi vọng sẽ giúp được bạn phần nào trong quá trình sử dụng SQL trong học tập cũng như khi làm việc. Kiến thức là vô tận, nắm vững cơ bản rồi, bạn có thể học giỏi hơn những gì có trong bài viết này!

Nếu bài viết có ích cho bạn, hãy like, share bạn nhé!

jumpie-adventure

Latest post
thumbnail thumbnail thumbnail thumbnail