Truy vấn con (Subquery)

Một phần của tài liệu giao trinh SQL (Trang 49)

Truy vấn con là một cõu lệnh SELECT được lồng vào bờn trong một cõu lệnh SELECT, INSERT, UPDATE, DELETE hoặc bờn trong một truy vấn con khỏc. Loại truy vấn này được sử dụng để biểu diễn cho những truy vấn trong đú điều kiện truy vấn dữ liệu cần phải sử dụng đến kết quả của một truy vấn khỏc.

(SELECT [ALL | DISTINCT] danh_sỏch_chọn FROM danh_sỏch_bảng

[WHERE điều_kiện] [GROUP BY danh_sỏch_cột] [HAVING điều_kiện])

Khi sử dụng truy vấn con cần lưu ý một số quy tắc sau:

• Một truy vấn con phải được viết trong cặp dấu ngoặc. Trong hầu hết cỏc trường hợp, một truy vấn con thường phải cú kết quả là một cột (tức là chỉ cú duy nhất một cột trong danh sỏch chọn).

• Mệnh đề COMPUTE và ORDER BY khụng được phộp sử dụng trong truy vấn con.

• Cỏc tờn cột xuất hiện trong truy vấn con cú thể là cỏc cột của cỏc bảng trong truy vấn ngoài.

• Một truy vấn con thường được sử dụng làm điều kiện trong mệnh đề WHERE hoặc HAVING của một truy vấn khỏc.

• Nếu truy vấn con trả về đỳng một giỏ trị, nú cú thể sử dụng như là một thành phần bờn trong một biểu thức (chẳng hạn xuất hiện trong một phộp so sỏnh bằng)

Phộp so sỏnh đối với với kết quả truy vấn con

Kết quả của truy vấn con cú thể được sử dụng đề thực hiện phộp so sỏnh số học với một biểu thức của truy vấn cha. Trong trường hợp này, truy vấn con được sử dụng dưới dạng:

WHERE biểu_thức phộp_toỏn_số_học [ANY|ALL] (truy_vấn_con)

Trong đú phộp toỏn số học cú thể sử dụng bao gồm: =, <>, >, <, >=, <=; Và truy vấn con phải cú kết quả bao gồm đỳng một cột.

Vớ dụ 2.43: Cõu lệnh dưới đõy cho biết danh sỏch cỏc mụn học cú số đơn vị học trỡnh lớn hơn hoặc bằng số đơn vị học trỡnh của mụn học cú mó là TI-001

SELECT * FROM monhoc

WHERE sodvht>=(SELECT sodvht FROM monhoc

WHERE mamonhoc='TI-001')

Nếu truy vấn con trả về nhiều hơn một giỏ trị, việc sử dụng phộp so sỏnh như trờn sẽ khụng hợp lệ. Trong trường hợp này, sau phộp toỏn so sỏnh phải sử dụng thờm lượng

từ ALL hoặc ANY. Lượng từ ALL được sử dụng khi cần so sỏnh giỏ trị của biểu thức với tất cả cỏc giỏ trị trả về trong kết quả của truy vấn con; ngược lai, phộp so sỏnh với lượng từ ANY cú kết quả đỳng khi chỉ cần một giỏ trị bất kỳ nào đú trong kết quả của truy vấn con thoả món điều kiện.

Vớ dụ 2.44: Cõu lệnh dưới đõy cho biết họ tờn của những sinh viờn lớp Tin K25 sinh trước tất cả cỏc sinh viờn của lớp Toỏn K25

SELECT hodem,ten

FROM sinhvien JOIN lop ON sinhvien.malop=lop.malop WHERE tenlop='Tin K25' AND

ngaysinh<ALL(SELECT ngaysinh

FROM sinhvien JOIN lop

ON sinhvien.malop=lop.malop WHERE lop.tenlop='Toỏn K25')

và cõu lệnh:

SELECT hodem,ten

FROM sinhvien JOIN lop on sinhvien.malop=lop.malop WHERE tenlop='Tin K25' AND

year(ngaysinh)= ANY(SELECT year(ngaysinh) FROM sinhvien JOIN lop ON sinhvien.malop=lop.malop WHERE lop.tenlop='Toỏn K25')

cho biết họ tờn của những sinh viờn lớp Tin K25 cú năm sinh trựng với năm sinh của bất kỳ một sinh viờn nào đú của lớp Toỏn K25.

Sử dụng truy vấn con với toỏn tử IN (adsbygoogle = window.adsbygoogle || []).push({});

Khi cần thực hiện phộp kiểm tra giỏ trị của một biểu thức cú xuất hiện (khụng xuất hiện) trong tập cỏc giỏ trị của truy vấn con hay khụng, ta cú thể sử dụng toỏn tử IN (NOT IN) như sau:

WHERE biểu_thức [NOT] IN (truy_vấn_con)

Vớ dụ 2.45: Để hiển thị họ tờn của những sinh viờn lớp Tin K25 cú năm sinh bằng với năm sinh của một sinh viờn nào đú của lớp Toỏn K25, thay vỡ sử dụng cõu lệnh như ở vớ dụ trờn, ta cú thể sử dụng cõu lệnh như sau:

SELECT hodem,ten

FROM sinhvien JOIN lop on sinhvien.malop=lop.malop WHERE tenlop='Tin K25' AND

year(ngaysinh)IN(SELECT year(ngaysinh) FROM sinhvien JOIN lop

ON sinhvien.malop=lop.malop WHERE lop.tenlop='Toỏn K25')

Sử dụng lượng từ EXISTS với truy vấn con

Lượng từ EXISTS được sử dụng kết hợp với truy vấn con dưới dạng:

WHERE [NOT] EXISTS (truy_vấn_con)

để kiểm tra xem một truy vấn con cú trả về dũng kết quả nào hay khụng. Lượng từ EXISTS (tương ứng NOT EXISTS) trả về giỏ trị True (tương ứng False) nếu kết quả của truy vấn con cú ớt nhất một dũng (tương ứng khụng cú dũng nào). Điều khỏc biệt của việc sử dụng EXISTS với hai cỏch đó nờu ở trờn là trong danh sỏch chọn của truy vấn con cú thể cú nhiều hơn hai cột.

Vớ dụ 2.46: Cõu lệnh dưới đõy cho biết họ tờn của những sinh viờn hiện chưa cú điểm thi của bất kỳ một mụn học nào

SELECT hodem,ten FROM sinhvien

WHERE NOT EXISTS(SELECT masv FROM diemthi

WHERE diemthi.masv=sinhvien.masv)

Sử dụng truy vấn con với mệnh đề HAVING

Một truy vấn con cú thể được sử dụng trong mệnh đề HAVING của một truy vấn khỏc. Trong trường hơp này, kết quả của truy vấn con được sử dụng để tạo nờn điều kiện đối với cỏc hàm gộp.

Vớ dụ 2.47: Cõu lệnh dưới đõy cho biết mó, tờn và trung bỡnh điểm lần 1 của cỏc mụn học cú trung bỡnh lớn hơn trung bỡnh điểm lần 1 của tất cả cỏc mụn học

SELECT diemthi.mamonhoc,tenmonhoc,AVG(diemlan1) FROM diemthi,monhoc

WHERE diemthi.mamonhoc=monhoc.mamonhoc GROUP BY diemthi.mamonhoc,tenmonhoc HAVING AVG(diemlan1)>

(SELECT AVG(diemlan1) FROM diemthi)

2.2 Bổ sung, cập nhật và xoỏ dữ liệu

Cỏc cõu lệnh thao tỏc dữ liệu trong SQL khụng những chỉ sử dụng để truy vấn dữ liệu mà cũn để thay đổi và cập nhật dữ liệu trong cơ sở dữ liệu. So với cõu lệnh SELECT, việc sử dụng cỏc cõu lệnh để bổ sung, cập nhật hay xoỏ dữ liệu đơn giản hơn nhiều. Trong phần cũn lại của chương này sẽ đề cập đến 3 cõu lệnh:

• Lệnh UPDATE

• Lệnh DELETE

2.2.1 Bổ sung dữ liệu

Dữ liệu trong cỏc bảng được thể hiện dưới dạng cỏc dũng (bản ghi). Để bổ sung thờm cỏc dũng dữ liệu vào một bảng, ta sử dụng cõu lệnh INSERT. Hầu hết cỏc hệ quản trị CSDL dựa trờn SQL cung cấp cỏc cỏch dưới đõy để thực hiện thao tỏc bổ sung dữ liệu cho bảng:

• Bổ sung từng dũng dữ liệu với mỗi cõu lệnh INSERT. Đõy là cỏc sử dụng thường gặp nhất trong giao tỏc SQL.

• Bổ sung nhiều dũng dữ liệu bằng cỏch truy xuất dữ liệu từ cỏc bảng dữ liệu khỏc.

Bổ sung từng dũng dữ liệu với lệnh INSERT (adsbygoogle = window.adsbygoogle || []).push({});

Để bổ sung một dũng dữ liệu mới vào bảng, ta sử dụng cõu lệnh INSERT với cỳ phỏp như sau:

INSERT INTO tờn_bảng[(danh_sỏch_cột)] VALUES(danh_sỏch_trị)

Trong cõu lệnh INSERT, danh sỏch cột ngay sau tờn bảng khụng cần thiết phải chỉ định nếu giỏ trị cỏc trường của bản ghi mới được chỉ định đầy đủ trong danh sỏch trị. Trong trường hợp này, thứ tự cỏc giỏ trị trong danh sỏch trị phải bằng với số lượng cỏc trường của bảng cần bổ sung dữ liệu cũng như phải tuõn theo đỳng thứ tự của cỏc trường như khi bảng được định nghĩa.

Vớ dụ 2.48: Cõu lệnh dưới đõy bổ sung thờm một dũng dữ liệu vào bảng KHOA

INSERT INTO khoa

VALUES(‘DHT10’,’Khoa Luật’,’054821135’)

Trong trường hợp chỉ nhập giỏ trị cho một số cột trong bảng, ta phải chỉ định danh sỏch cỏc cột cần nhập dữ liệu ngay sau tờn bảng. Khi đú, cỏc cột khụng được nhập dữ liệu sẽ nhận giỏ trị mặc định (nếu cú) hoặc nhận giỏ trị NULL (nếu cột cho phộp chấp nhận giỏ trị NULL). Nếu một cột khụng cú giỏ trị mặc định và khụng chấp nhận giỏ trị NULL mà khụng đuợc nhập dữ liệu, cõu lệnh sẽ bị lỗi.

Vớ dụ 2.49: Cõu lệnh dưới đõy bổ sung một bản ghi mới cho bảng SINHVIEN

INSERT INTO sinhvien(masv,hodem,ten,gioitinh,malop) VALUES(‘0241020008’,‘Nguyễn Cụng’,’Chớnh’,1,’C24102’)

cõu lệnh trờn cũn cú thể được viết như sau:

VALUES(‘0241020008’,‘Nguyễn Cụng’,’Chớnh’, NULL,1,NULL,’C24102’)

Bổ sung nhiều dũng dữ liệu từ bảng khỏc

Một cỏch sử dụng khỏc của cõu lệnh INSERT được sử dụng để bổ sung nhiều dũng dữ liệu vào một bảng, cỏc dũng dữ liệu này được lấy từ một bảng khỏc thụng qua cõu lệnh SELECT. Ở cỏch này, cỏc giỏ trị dữ liệu được bổ sung vào bảng khụng được chỉ định tường minh mà thay vào đú là một cõu lệnh SELECT truy vấn dữ liệu từ bảng khỏc.

Cỳ phỏp cõu lệnh INSERT cú dạng như sau:

INSERT INTO tờn_bảng[(danh_sỏch_cột)] cõu_lệnh_SELECT

Vớ dụ 2.50: Giả sử ta cú bảng LUUSINHVIEN bao gồm cỏc trường HODEM, TEN, NGAYSINH. Cõu lệnh dưới đõy bổ sung vào bảng LUUSINHVIEN cỏc dũng dữ liệu cú được từ cõu truy vấn SELECT:

INSERT INTO luusinhvien SELECT hodem,ten,ngaysinh FROM sinhvien

WHERE noisinh like ‘%Huế%’

Khi bổ sung dữ liệu theo cỏch này cần lưu ý một số điểm sau:

• Kết quả của cõu lệnh SELECT phải cú số cột bằng với số cột được chỉ định trong bảng đớch và phải tương thớch về kiểu dữ liệu.

• Trong cõu lệnh SELECT được sử dụng mệnh đề COMPUTE ... BY

2.2.2 Cập nhật dữ liệu

Cõu lệnh UPDATE trong SQL được sử dụng để cập nhật dữ liệu trong cỏc bảng. Cõu lệnh này cú cỳ phỏp như sau:

UPDATE tờn_bảng

SET tờn_cột = biểu_thức

[, ..., tờn_cột_k = biểu_thức_k] [FROM danh_sỏch_bảng]

[WHERE điều_kiện]

Sau UPDATE là tờn của bảng cần cập nhật dữ liệu. Một cõu lệnh UPDATE cú thể cập nhật dữ liệu cho nhiều cột bằng cỏch chỉ định cỏc danh sỏch tờn cột và biểu thức tương ứng sau từ khoỏ SET. Mệnh đề WHERE trong cõu lệnh UPDATE thường được sử dụng

để chỉ định cỏc dũng dữ liệu chịu tỏc động của cõu lệnh (nếu khụng chỉ định, phạm vi tỏc động của cõu lệnh được hiểu là toàn bộ cỏc dũng trong bảng)

Vớ dụ 2.51: Cõu lệnh dưới đõy cập nhật lại số đơn vị học trỡnh của cỏc mụn học cú số đơn vị học trỡnh nhỏ hơn 2 (adsbygoogle = window.adsbygoogle || []).push({});

UPDATE monhoc SET sodvht = 3 WHERE sodvht = 2

Sử dụng cấu trỳc CASE trong cõu lệnh UPDATE

Cấu trỳc CASE cú thể được sử dụng trong biểu thức khi cần phải đưa ra cỏc quyết định khỏc nhau về giỏ trị của biểu thức

Vớ dụ 2.52: Giả sử ta cú bảng NHATKYPHONG sau đõy

Sau khi thực hiện cõu lệnh:

UPDATE nhatkyphong

SET tienphong=songay*CASE WHEN loaiphong='A' THEN 100 WHEN loaiphong='B' THEN 70 ELSE 50

END

Dữ liệu trong bảng sẽ là:

Điều kiện cập nhật dữ liệu liờn quan đến nhiều bảng

Mệnh đề FROM trong cõu lệnh UPDATE được sử dụng khi cần chỉ định cỏc điều kiện liờn quan đến cỏc bảng khỏc với bảng cần cập nhật dữ liệu. Trong truờng hợp này, trong mệnh đề WHERE thường cú điều kiện nối giữa cỏc bảng.

Vớ dụ 2.53: Giả sử ta cú hai bảng MATHANG và NHATKYBANHANG như sau:

Cõu lệnh dưới đõy sẽ cập nhật giỏ trị trường THANHTIEN của bảng NHATKYBANHANG theo cụng thức THANHTIEN = SOLUONG ì GIA

UPDATE nhatkybanhang

SET thanhtien = soluong*gia FROM mathang

WHERE nhatkybanhang.mahang = mathang.mahang

Cõu lệnh UPDATE với truy vấn con

Tương tự như trong cõu lệnh SELECT, truy vấn con cú thể được sử dụng trong mệnh đề WHERE của cõu lệnh UPDATE nhằm chỉ định điều kiện đối với cỏc dũng dữ liệu cần cập nhật dữ liệu.

Vớ dụ 2.54: Cõu lệnh ở trờn cú thể được viết như sau:

UPDATE nhatkybanhang

SET thanhtien = soluong*gia FROM mathang

WHERE mathang.mahang =(SELECT mathang.mahang FROM mathang

WHERE mathang.mahang=nhatkybanhang.mahang)

2.2.3 Xoỏ dữ liệu

Để xoỏ dữ liệu trong một bảng, ta sử dụng cõu lệnh DELETE. Cỳ phỏp của cõu lệnh này như sau:

DELETE FROM tờn_bảng [FROM danh_sỏch_bảng] [WHERE điều_kiện]

Trong cõu lệnh này, tờn của bảng cần xoỏ dữ liệu được chỉ định sau DELETE FROM. Mệnh đề WHERE trong cõu lệnh được sử dụng để chỉ định điều kiện đối với cỏc dũng dữ liệu cần xoỏ. Nếu cõu lệnh DELETE khụng cú mệnh đề WHERE thỡ toàn bộ cỏc dũng dữ liệu trong bảng đều bị xoỏ.

Vớ dụ 2.55: Cõu lệnh dưới đõy xoỏ khỏi bảng SINHVIEN những sinh viờn sinh tại Huế

WHERE noisinh LIKE ‘%Huế%’

Xoỏ dữ liệu khi điều kiện liờn quan đến nhiều bảng (adsbygoogle = window.adsbygoogle || []).push({});

Nếu điều kiện trong cõu lệnh DELETE liờn quan đến cỏc bảng khụng phải là bảng cần xúa dữ liệu, ta phải sử dụng thờm mệnh đề FROM và sau đú là danh sỏch tờn cỏc bảng đú. Trong trường hợp này, trong mệnh đề WHERE ta chỉ định thờm điều kiện nối giữa cỏc bảng

Vớ dụ 2.56: Cõu lệnh dưới đõy xoỏ ra khỏi bảng SINHVIEN những sinh viờn lớp Tin K24

DELETE FROM sinhvien FROM lop

WHERE lop.malop=sinhvien.malop AND tenlop='Tin K24'

Sử dụng truy vấn con trong cõu lệnh DELETE

Một cõu lệnh SELECT cú thể được lồng vào trong mệnh đề WHERE trong cõu lệnh DELETE để làm điều kiện cho cõu lệnh tương tự như cõu lệnh UPDATE.

Vớ dụ 2.57: Cõu lệnh dưới đõy xoỏ khỏi bảng LOP những lớp khụng cú sinh viờn nào học

DELETE FROM lop

WHERE malop NOT IN (SELECT DISTINCT malop FROM sinhvien)

Xoỏ toàn bộ dữ liệu trong bảng

Cõu lệnh DELETE khụng chỉ định điều kiện đối với cỏc dũng dữ liệu cần xoỏ trong mệnh đề WHERE sẽ xoỏ toàn bộ dữ liệu trong bảng. Thay vỡ sử dụng cõu lệnh DELETE trong trường hợp này, ta cú thể sử dụng cõu lệnh TRUNCATE cú cỳ phỏp như sau:

TRUNCATE TABLE tờn_bảng

Vớ dụ 2.58: Cõu lệnh sau xoỏ toàn bộ dữ liệu trong bảng diemthi:

DELETE FROM diemthi

cú tỏc dụng tương tự với cõu lệnh

TRUNCATE TABLE diemthi

Bài tập chương 2

Cơ sở dữ liệu dưới đõy được sử dụng để quản lý cụng tỏc giao hàng trong một cụng ty kinh doanh. Cỏc bảng trong cơ sở dữ liệu này được biểu diễn trong sơ đồ dưới đõy:

Trong đú:

• Bảng NHACUNGCAP lưu trữ dữ liệu về cỏc đối tỏc cung cấp hàng cho cụng ty.

• Bảng MATHANG lưu trữ dữ liệu về cỏc mặt hàng hiện cú trong cụng ty.

• Bảng LOAIHANG phõn loại cỏc mặt hàng hiện cú.

• Bảng NHANVIEN cú dữ liệu là thụng tin về cỏc nhõn viờn làm việc trong cụng ty.

• Bảng KHACHHANG được sử dụng để lưu giữ thụng tin về cỏc khỏch hàng của cụng ty.

• Khỏch hàng đặt hàng cho cụng ty thụng qua cỏc đơn đặt hàng. Thụng tin chung về cỏc đơn đặt hàng được lưu trữ trong bảng DONDATHANG (Mỗi một đơn đặt hàng phải do một nhõn viờn của cụng ty lập và do đú bảng này cú quan hệ với bảng NHANVIEN)

• Thụng tin chi tiết của cỏc đơn đặt hàng (đặt mua mặt hàng gỡ, số lượng, giỏ cả,...) được lưu trữ trong bảng CHITIETDATHANG. Bảng này cú quan hệ với hai bảng DONDATHANG và MATHANG.

Sử dụng cõu lệnh SELECT để viết cỏc yờu cầu truy vấn dữ liệu sau đõy: 2. 1 Cho biết danh sỏch cỏc đối tỏc cung cấp hàng cho cụng ty.

2. 2 Mó hàng, tờn hàng và số lượng của cỏc mặt hàng hiện cú trong cụng ty. 2. 3 Họ tờn và địa chỉ và năm bắt đầu làm việc của cỏc nhõn viờn trong cụng ty. 2. 4 Địa chỉ và điện thoại của nhà cung cấp cú tờn giao dịch VINAMILK là gỡ?

2. 5 Cho biết mó và tờn của cỏc mặt hàng cú giỏ lớn hơn 100000 và số lượng hiện cú ớt hơn 50.

2. 6 Cho biết mỗi mặt hàng trong cụng ty do ai cung cấp. 2. 7 Cụng ty Việt Tiến đó cung cấp những mặt hàng nào? (adsbygoogle = window.adsbygoogle || []).push({});

2. 8 Loại hàng thực phẩm do những cụng ty nào cung cấp và địa chỉ của cỏc cụng ty đú là gỡ?

2. 9 Những khỏch hàng nào (tờn giao dịch) đó đặt mua mặt hàng Sữa hộp XYZ của cụng ty?

2. 10 Đơn đặt hàng số 1 do ai đặt và do nhõn viờn nào lập, thời gian và địa điểm giao hàng là ở đõu?

2. 11 Hóy cho biết số tiền lương mà cụng ty phải trả cho mỗi nhõn viờn là bao nhiờu (lương = lương cơ bản + phụ cấp).

2. 12 Trong đơn đặt hàng số 3 đặt mua những mặt hàng nào và số tiền mà khỏch hàng phải trả cho mỗi mặt hàng là bao nhiờu (số tiền phải trả được tớnh theo cụng thức SOLUONGìGIABAN – SOLUONGìGIABANìMUCGIAMGIA/100)

2. 13 Hóy cho biết cú những khỏch hàng nào lại chớnh là đối tỏc cung cấp hàng của cụng ty (tức là cú cựng tờn giao dịch).

2. 14 Trong cụng ty cú những nhõn viờn nào cú cựng ngày sinh?

2. 15 Những đơn đặt hàng nào yờu cầu giao hàng ngay tại cụng ty đặt hàng và những đơn đú là của cụng ty nào?

2. 16 Cho biết tờn cụng ty, tờn giao dịch, địa chỉ và điện thoại của cỏc khỏch hàng và cỏc nhà cung cấp hàng cho cụng ty.

2. 17 Những mặt hàng nào chưa từng được khỏch hàng đặt mua?

2. 18 Những nhõn viờn nào của cụng ty chưa từng lập bất kỳ một hoỏ đơn đặt hàng nào? 2. 19 Những nhõn viờn nào của cụng ty cú lương cơ bản cao nhất?

2. 20 Tổng số tiền mà khỏch hàng phải trả cho mỗi đơn đặt hàng là bao nhiờu? 2. 21 Trong năm 2003, những mặt hàng nào chỉ được đặt mua đỳng một lần.

2. 22 Hóy cho biết mỗi một khỏch hàng đó phải bỏ ra bao nhiờu tiền để đặt mua hàng

Một phần của tài liệu giao trinh SQL (Trang 49)