Tải bản đầy đủ (.pdf) (44 trang)

Hướng dẫn SQL & XQuery cho IBM DB2, Phần 5: So sánh dữ liệu

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (238.45 KB, 44 trang )

Hướng dẫn SQL & XQuery cho IBM DB2,
Phần 5: So sánh dữ liệu
Sử dụng các truy vấn nâng cao để so sánh dữ liệu
Jessica Cao, Chuyên viên phát triển các công cụ đào tạo, IBM
Bruce Creighton, Chuyên viên lập kế hoạch các phần kỹ năng, IBM
Pat Moffatt, Giám đốc Chương trình quản lý thơng tin, Sáng kiến học đường, IBM
Tóm tắt: Hướng dẫn này mô tả các truy vấn để so sánh dữ liệu trong một cơ sở
dữ liệu IBM® DB2®. Điều này được thực hiện bằng các biểu thức CASE hoặc
các truy vấn con. Hướng dẫn này là Phần 5 của loạt bài hướng dẫn SQL &
XQuery cho IBM DB2.
Trước khi bạn bắt đầu

Về loạt bài này
Loạt bài hướng dẫn này dạy các chủ đề SQL từ cơ bản đến nâng cao và các chủ đề
XQuery cơ bản. Nó cũng chỉ ra cách diễn đạt các câu hỏi nghiệp vụ thường gặp
bằng các truy vấn cơ sở dữ liệu sử dụng các câu truy vấn SQL hay các câu truy
vấn XQuery. Những người phát triển ứng dụng và những người quản trị cơ sở dữ
liệu có thể sử dụng hướng dẫn này để nâng cao các kỹ năng truy vấn cơ sở dữ liệu
của mình. Các thành viên tham gia sáng kiến học đường IBM có thể sử dụng loạt
hướng dẫn này như một phần trong chương trình giảng dạy cơ sở dữ liệu của họ.
Tất cả các ví dụ trong bài này là dựa trên Aroma, một cơ sở dữ liệu mẫu chứa các
dữ liệu doanh thu về các sản phẩm cà phê và chè đã bán trong các cửa hàng trên
khắp nước Mỹ. Mỗi ví dụ gồm có ba phần:


Một câu hỏi kinh doanh dưới dạng ngơn ngữ thường ngày



Một hoặc nhiều ví dụ truy vấn , được biểu diễn bằng SQL hay Xquery




Một bảng các kết quả trả về từ cơ sở dữ liệu


Hướng dẫn này được thiết kế để cho phép các học viên học tập ngôn ngữ SQL và
XQuery. Cũng như học bất cứ cái gì khác, việc bổ sung thêm các bài tập thực hành
là rất quan trọng. Dữ liệu và các định nghĩa bảng sẽ tạo điều kiện thuận lợi cho các
bài tập thực hành này.
Đối với các sinh viên sử dụng tài liệu này như một phần của khố học, hãy nhận từ
thầy hướng dẫn của mình các chỉ dẫn để kết nối tới cơ sở dữ liệu Aroma và tìm
hiểu mọi sự khác biệt giữa hướng dẫn và cài đặt tại máy cục bộ của mình.
Hướng dẫn này được viết cho DB2 9 Express-C trên nền UNIX®, Linux® và
Windows® (trước đây gọi là Viper).
Về hướng dẫn này
Hướng dẫn này thảo luận về các truy vấn dùng để so sánh dữ liệu trong một cơ sở
dữ liệu DB2 của IBM. Nó bắt đầu bằng cách minh họa vấn đề mà người viết truy
vấn phải đối phó: cách sử dụng SQL để trả về một bảng tính hay báo cáo "tổng
hợp" chứ không phải một tập hợp kết quả tiêu chuẩn, sắp xếp theo thứ tự thẳng
đứng rất khó đọc. Vấn đề này được giải quyết bằng các biểu thức CASE hoặc các
truy vấn phụ.
Giải pháp CASE, được giới thiệu đầu tiên, là một cách đơn giản và ngắn gọn để so
sánh các nhóm các giá trị tương tự nhau. Tiếp theo sẽ trình bày một vài ví dụ của
mệnh đề FROM và các truy vấn phụ của danh sách chọn lựa. Các truy vấn phụ này
có thêm giá trị ở chỗ có thể vừa so sánh dữ liệu từ các nhóm khác nhau và vừa
gồm các tính tốn đối với các giá trị được so sánh, ví dụ như là các phần trăm
đóng góp trong các thời hạn đã cho.
Hướng dẫn này mô tả các truy vấn phụ được tuyên bố như là các điều kiện trong
mệnh đề WHERE, có ích cho các truy vấn so sánh đơn giản. Phần cuối cùng cũng
mơ tả các thuộc tính ALL, EXISTS, và SOME hoặc ANY. Các thuộc tínhnày có

thể được dùng để biểu diễn các điều kiện đối với kết quả của truy vấn phụ.
Kết nối tới một cơ sở dữ liệu
Bạn cần kết nối tới một cơ sở dữ liệu trước khi có thể sử dụng các câu lệnh SQL
để truy vấn hay xử lý dữ liệu. Lệnh CONNECT kết hợp một kết nối cơ sở dữ liệu
với một tên người sử dụng.
Thơng qua người hướng dẫn tìm ra tên cơ sở dữ liệu bạn cần nối tới. Đối với loạt
bài này, tên cơ sở dữ liệu là aromadb.


Để kết nối tới cơ sở dữ liệu aromadb, gõ lệnh sau đây vào trong bộ xử lý dòng
lệnh DB2:
CONNECT TO aromadb USER userid USING password

Thay thế "userid" và "password" bằng số ID và mật khẩu của người sử dụng mà
bạn đã nhận được từ thầy hướng dẫn. Nếu máy khơng hỏi userid và password thì
chỉ cần gõ vào lệnh sau đây:

CONNECT TO aromadb

Thông điệp sau báo cho bạn biết rằng đã tạo kết nối thành công:
Database Connection Information
Database server

= DB2/NT 9.0.0

SQL authorization ID = USERID
Local database alias = AROMADB

Khi đã kết nối được, bạn có thể bắt đầu sử dụng cơ sở dữ liệu.
So sánh dữ liệu bằng câu hỏi SQL

Câu hỏi
So sánh doanh thu của cà phê đóng gói tại các cửa hàng ở vùng phía Tây trong
năm 2004 ra sao?


Ví dụ truy vấn
SELECT store_name, prod_name, SUM(dollars) AS sales
FROM aroma.market a,
aroma.store b,
aroma.period c,
aroma.product d,
aroma.class e,
aroma.sales f
WHERE a.mktkey = b.mktkey
AND b.storekey = f.storekey
AND c.perkey = f.perkey
AND d.classkey = e.classkey
AND d.classkey = f.classkey
AND d.prodkey = f.prodkey
AND region like 'West%'
AND year = 2004
AND class_type = 'Pkg_coffee'
GROUP BY store_name, prod_name
ORDER BY store_name, prod_name;

Kết quả


STORE_NAME


PROD_NAME

SALES

Beaches Brew

Aroma Roma

3483.50

Beaches Brew

Cafe Au Lait

3129.50

Beaches Brew

Colombiano

2298.25

Beaches Brew

Demitasse Ms

4529.25

Beaches Brew


Expresso XO

4132.75

Beaches Brew

La Antigua

4219.75

Beaches Brew

Lotta Latte

3468.00

Beaches Brew

NA Lite

4771.00

Beaches Brew

Veracruzano

4443.00

Beaches Brew


Xalapa Lapa

4304.00

Cupertino Coffee Supply

Aroma Roma

4491.00

Cupertino Coffee Supply

Cafe Au Lait

4375.50

Cupertino Coffee Supply

Colombiano

2653.50


Cupertino Coffee Supply

Demitasse Ms

3936.50

Cupertino Coffee Supply


Expresso XO

4689.25

Cupertino Coffee Supply

La Antigua

2932.00

Cupertino Coffee Supply

Lotta Latte

5146.00

Cupertino Coffee Supply

NA Lite

4026.00

Cupertino Coffee Supply

Veracruzano

3285.00

Cupertino Coffee Supply


Xalapa Lapa

5784.00

Instant Coffee

Aroma Roma

3485.25

Instant Coffee

Cafe Au Lait

3599.50

Instant Coffee

Colombiano

3321.75

Instant Coffee

Demitasse Ms

5422.25

Instant Coffee


Expresso XO

2851.00

Instant Coffee

La Antigua

2937.25

Instant Coffee

Lotta Latte

4783.50


Instant Coffee

NA Lite

3740.00

Instant Coffee

Veracruzano

4712.00


Instant Coffee

Xalapa Lapa

3698.00

...

Một truy vấn so sánh đơn giản
Bạn có thể liệt kê doanh thu của một nhóm các sản phẩm tại các cửa hàng cụ thể
bằng một lệnh SELECT đơn giản, nhưng định dạng của bảng kết quả làm cho các
giá trị khó so sánh được. Ví dụ, tập hợp kết quả của phần trên cho thấy cà phê La
Antigua đã bán ra tại một vài cửa hàng trong vùng phía tây, nhưng các con số này
rất khó tách ra.
Loại dữ liệu này sẽ dễ so sánh hơn nhiều khi nó được định dạng như một bảng
tính. Có hai cách để tạo ra một báo cáo bảng tính, hay báo cáo "tổng hợp": sử dụng
các biểu thức CASE hay các truy vấn phụ. Các ví dụ tiếp sau trong hướng dẫn này
minh họa cả hai phương pháp viết các truy vấn so sánh.
Về truy vấn
Ví dụ truy vấn trả về các số doanh thu năm 2004 của các sản phẩm cà phê đóng
gói bán tại mỗi cửa hàng trong vùng phía tây, nhưng định dạng của dữ liệu kết quả
làm cho nó trở nên khó so sánh các con số theo từng sản phẩm, theo từng cửa hàng
với nhau.
Sử dụng các biểu thức CASE
Câu hỏi
So sánh doanh thu của cà phê đóng gói tại các cửa hàng ở vùng phía Tây trong
năm 2004 như thế nào?


Ví dụ truy vấn

SELECT prod_name,
SUM(CASE WHEN store_name = 'Beaches Brew'
then dollars else 0 end) AS Beaches,
SUM(CASE WHEN store_name = 'Cupertino Coffee
Supply'
then dollars else 0 end) AS Cupertino,
SUM(CASE WHEN store_name = 'Roasters, Los
Gatos'
then dollars else 0 end) AS RoastLG,
SUM(CASE WHEN store_name = 'San Jose Roasting
Company'
then dollars else 0 end) AS SJRoastCo,
SUM(CASE WHEN store_name = 'Java Judy''s'
then dollars else 0 end) AS JavaJudy,
SUM(CASE WHEN store_name = 'Instant Coffee'
then dollars else 0 end) AS Instant
FROM aroma.market a,
aroma.store b,
aroma.period c,
aroma.product d,
aroma.class e,
aroma.sales f


WHERE a.mktkey = b.mktkey
AND b.storekey = f.storekey
AND c.perkey = f.perkey
AND d.classkey = e.classkey
AND d.classkey = f.classkey
AND d.prodkey = f.prodkey

AND region LIKE 'West%'
AND year = 2004
AND class_type = 'Pkg_coffee'
GROUP BY prod_name
ORDER BY prod_name;

Kết quả
PROD_NAMEBEACHESCUPERTINOROASTLGSJROASTCOJAVAJUDYINSTANT
Aroma Roma

3483.50

4491.00

4602.00

4399.25

3748.25

3485.25

Cafe Au Lait

3129.50

4375.50

4199.00


3620.00

4864.50

3599.50

Colombiano

2298.25

2653.50

4205.00

3530.75

3509.00

3321.75


Demitasse Ms 4529.25

3936.50

4347.75

5699.00

6395.25


5422.25

Expresso XO

4132.75

4689.25

4234.50

3811.00

5012.25

2851.00

La Antigua

4219.75

2932.00

3447.50

4323.00

2410.25

2937.25


Lotta Latte

3468.00

5146.00

4469.50

5103.50

4003.00

4783.50

NA Lite

4771.00

4026.00

3250.00

2736.00

4791.00

3740.00

Veracruzano


4443.00

3285.00

4467.00

3856.00

4510.00

4712.00

Xalapa Lapa

4304.00

5784.00

3906.00

3645.00

3182.00

3698.00

Một giải pháp để so sánh dữ liệu: các biểu thức CASE
Một cách hiệu quả và ngắn gọn để hiển thị các giá trị so sánh theo một định dạng
bảng tính dễ đọc là sử dụng các biểu thức CASE trong danh sách chọn lựa. Mỗi

phép tính CASE đánh giá một biểu thức đã chỉ rõ và cung cấp một giá trị khác
nhau, phụ thuộc vào một điều kiện nhất định có được đáp ứng hay khơng.

Cú pháp CASE
Nói chung, bạn xây dựng một truy vấn so sánh CASE bằng cách chỉ rõ những ràng
buộc trên tồn bộ miền mà trên đó các kết quả được sinh ra trong mệnh đề
WHERE của truy vấn chính hay là truy vấn ngồi. Sau đó, bạn phân chia kết quả
thành các tập con với một biểu thức CASE trong danh sách lựa chọn:


CASE WHEN search_condition THEN result1 ELSE result2
END AS col_alias

search_condition

Một điều kiện lơgíc được đánh giá đúng hay sai.

result1

Một giá trị được dùng khi search_condition là đúng.

result2

Một giá trị mặc định khi search_condition là sai.

Chú ý quan trọng: Một biểu thức CASE có thể ở một trong hai dạng: đơn
giản hay có tìm kiếm. Ví dụ này sử dụng dạng có tìm kiếm. Để biết thêm
chi tiết, tham khảo SQL Reference Guide (Hướng dẫn tham khảo SQL) .

Về truy vấn

Truy vấn này đặt ra cùng một câu hỏi kinh doanh giống như truy vấn trước trong
hướng dẫn này. Tuy nhiên, trong trường hợp này biểu thức CASE được dùng để
tạo ra sáu cột khác nhau trong tập hợp kết quả. Tập hợp kết quả này có chứa tổng
các giá trị đơla, một cột cho mỗi cửa hàng.
Sử dụng các truy vấn phụ trong mệnh đề FROM
Câu hỏi
Doanh thu sản phẩm tại San Jose trong tháng Giêng 2004 so với doanh thu sản
phẩm này hàng năm trong cùng thành phố trong cùng năm là như thế nào?
Ví dụ truy vấn


SELECT sales1.product, jan_04_sales, total_04_sales
FROM
(SELECT prod_name, SUM(dollars)
FROM aroma.product a,
aroma.sales b,
aroma.period c,
aroma.store d
WHERE a.prodkey = b.prodkey
AND a.classkey = b.classkey
AND c.perkey = b.perkey
AND d.storekey = b.storekey
AND c.year = 2004
AND c.month = 'JAN'
AND d.city LIKE 'San J%'
GROUP BY a.prod_name) AS sales1(product,
jan_04_sales)
,
(SELECT prod_name, SUM(dollars) AS
total_04_sales

FROM aroma.product a,
aroma.sales b,
aroma.period c,


aroma.store d
WHERE a.prodkey = b.prodkey
AND a.classkey = b.classkey
AND c.perkey = b.perkey
AND d.storekey = b.storekey
AND c.year = 2004
AND d.city LIKE 'San J%'
GROUP BY a.prod_name) AS sales2(product,
total_04_sales)
WHERE sales1.product = sales2.product
ORDER BY sales1.product;

Kết quả
PRODUCT

JAN_04_SALES

TOTAL_04_SALES

Aroma Roma

1653.00

21697.50


Aroma Sheffield Steel Teapot

120.00

1122.00

Aroma Sounds Cassette

58.50

866.00


Aroma baseball cap

7.95

2960.15

Aroma t-shirt

470.85

4470.50

Assam Gold Blend

652.00

11375.00


Assam Grade A

352.00

5429.00

Breakfast Blend

608.25

6394.75

Cafe Au Lait

1936.50

24050.50

Colombiano

2148.00

22528.50

Darjeeling Number 1

867.50

8590.00


Darjeeling Special

1355.00

17787.50

Demitasse Ms

2163.00

35523.50

Earl Grey

540.50

6608.50

English Breakfast

393.00

5365.50

Espresso Machine Italiano

899.55

4397.80


Expresso XO

2935.50

27362.00


French Press, 2-Cup

104.65

1196.00

French Press, 4-Cup

19.95

1109.20

Gold Tips

440.00

5381.50

Irish Breakfast

703.25


7455.50

...

Một giải pháp linh hoạt hơn: Các truy vấn phụ trong mệnh đề FROM
Một truy vấn phụ là biểu thức truy vấn bất kỳ trong dấu ngoặc xuất hiện bên trong
câu hỏi khác. Một truy vấn phụ đôi khi được gọi là một truy vấn bên trong. Truy
vấn bên trong hoạt động bên trong truy vấn phía ngồi, hay như là truy vấn con
của một truy vấn cha mẹ.
Về truy vấn
Một giá trị thường được so sánh với một tổng của một tập hợp các giá trị. Ví dụ
truy vấn so sánh doanh thu sản phẩm ở San Jose trong tháng Giêng 2004 với
doanh thu ở San Jose suốt cả năm 2004. Loại truy vấn này yêu cầu các phép gộp
hỗn hợp; bởi vậy, khơng thể viết loại truy vấn đó bằng các biểu thức CASE vì biểu
thức CASE phải hoạt động theo các giá trị bên trong một nhóm đơn hay một phạm
vi. Thay vào đó, các truy vấn phụ trong mệnh đề FROM được dùng để thực hiện
so sánh.

Chú ý quan trọng: Bất kỳ truy vấn nào mà có thể được biểu diễn như một
truy vấn phụ trong mệnh đề FROM cũng có thể được biểu diễn như một
truy vấn phụ trong danh sách chọn lựa, như sẽ cho thấy ở phần sau trong
hướng dẫn này.


Các lưu ý về cách dùng
Ví dụ truy vấn dựa vào tính linh hoạt của biểu thức truy vấn trong SQL tiêu chuẩn
để kết nối các kết quả của hai truy vấn phụ. Để biết thêm thông tin chi tiết về các
biểu thức truy vấn, xem SQL Reference Guide .
Các bảng dẫn xuất từ kết quả đánh giá của các truy vấn phụ có thể được kết nối
với các tham chiếu bảng khác. Với mục đích này, một truy vấn phụ trong mệnh đề

FROM phải có một tên tương quan. Ví dụ, các truy vấn phụ trong ví dụ này được
đánh giá thành các bảng sau đây:
sales1(product, jan_04_sales)
sales2(product, total_04_sales)

Phép nối các bảng này (qua cột Product) tạo ra một bảng phát sinh khơng tên có
ba cột, là nguồn của ba mục của danh sách chọn lựa trong truy vấn chính:
product, jan_04_sales, total_04_sales

Thực hiện các tính tốn và các so sánh
Câu hỏi
Doanh thu sản phẩm trong Tháng Giêng 2004 tại San Jose chiếm bao nhiêu phần
trăm của doanh thu sản phẩm hàng năm trong cùng thành phố? Mười sản phẩm
bán chạy nhất theo tỷ lệ phần trăm đó là gì?
Ví dụ truy vấn
SELECT sales1.product, jan_04_sales, total_04_sales,
DEC((100.00 * jan_04_sales/total_04_sales),7,2) AS


pct_of_04
FROM
(SELECT a1.prod_name, SUM(dollars)
FROM aroma.product a1,
aroma.sales b1,
aroma.period c1,
aroma.store d1
WHERE a1.prodkey = b1.prodkey
AND a1.classkey = b1.classkey
AND c1.perkey = b1.perkey
AND d1.storekey = b1.storekey

AND c1.year = 2004
AND c1.month = 'JAN'
AND d1.city LIKE 'San J%'
GROUP BY a1.prod_name) AS sales1(product,
jan_04_sales)
,
(SELECT a2.prod_name, SUM(dollars)
FROM aroma.product a2,
aroma.sales b2,
aroma.period c2,
aroma.store d2


WHERE a2.prodkey = b2.prodkey
AND a2.classkey = b2.classkey
AND c2.perkey = b2.perkey
AND d2.storekey = b2.storekey
AND c2.year = 2004
AND d2.city LIKE 'San J%'
GROUP BY a2.prod_name) AS sales2(product,
total_04_sales)
WHERE sales1.product = sales2.product
ORDER BY pct_of_04 DESC
FETCH FIRST 10 ROWS ONLY;

Kết quả
PRODUCT

JAN_04_SALES TOTAL_04_SALES PCT_OF_04


Espresso Machine Italiano

899.55

4397.80

20.45

La Antigua

2643.25

22244.50

11.88

Expresso XO

2935.50

27362.00

10.72


Aroma Sheffield Steel Teapot 120.00

1122.00

10.69


Aroma t-shirt

470.85

4470.50

10.53

Lotta Latte

3195.00

31200.00

10.24

Darjeeling Number 1

867.50

8590.00

10.09

Colombiano

2148.00

22528.50


9.53

Breakfast Blend

608.25

6394.75

9.51

Irish Breakfast

703.25

7455.50

9.43

Các tính tốn với các truy vấn phụ của mệnh đề FROM
Tập hợp kết quả của một truy vấn so sánh có thể được sử dụng như dữ liệu nguồn
cho các tính tốn khác nhau. Ví dụ, một tổng doanh thu hàng tháng của một sản
phẩm có thể được biểu diễn như phần đóng góp trong doanh thu hàng năm với
cách tính tốn tỷ lệ phần trăm đơn giản:
100.00 * monthly_sales / annual_sales

Các truy vấn phụ trong mệnh đề FROM có thể dùng để tính tốn các tỷ lệ phần
trăm hay phần đóng góp theo thị trường, theo sản phẩm và theo các khoảng thời
gian.
Về truy vấn



Dựa vào ví dụ trước, truy vấn này tính tốn các số doanh thu hàng tháng cho từng
sản phẩm ở San Jose như phần đóng góp hoặc tỷ lệ phần trăm của doanh thu hàng
năm của sản phẩm đó trong cùng thành phố. Tập hợp kết quả có thể tạo ra một
danh sách xếp hạng dựa vào quyết định sắp xếp của bạn.
Các con số trong cột Pct_of_04 không tổng cộng thành 100 vì các con số này
tương ứng với tỷ lệ phần trăm của một tháng trong một năm cho doanh thu của
mỗi sản phẩm riêng lẻ, không phải tỷ lệ phần trăm của doanh thu hàng tháng trong
toàn bộ doanh thu hàng năm.
Biểu đồ này cho thấy doanh thu trong tháng Giêng chiếm một vài phần trăm của
doanh thu suốt cả năm. Ví dụ, các ấm chè được bán trong tháng Giêng
chiếm10.69% của tổng doanh thu ấm chè năm.
Sử dụng các truy vấn phụ trong danh sách SELECT
Câu hỏi
Trong những ngày nào của tháng Mười Hai năm 2005 có các số doanh thu Lotta
Latte tại cơng ty Roasting San Jose thấp hơn số doanh thu trung bình hàng ngày
của cùng sản phẩm tại cùng cửa hàng trong tháng Mười Hai 2004? Hiển thị trung
bình hằng ngày cho năm 2004 theo một cột riêng.
Ví dụ truy vấn
SELECT prod_name, store_name, date, dollars AS sales_05,
(SELECT DEC(AVG(dollars),7,2)
FROM aroma.product a,
aroma.sales b,
aroma.period c,
aroma.store d
WHERE a.prodkey = b.prodkey
AND a.classkey = b.classkey



AND c.perkey = b.perkey
AND d.storekey = b.storekey
AND year = 2004
AND month = 'DEC'
AND store_name = 'San Jose Roasting Company'
AND prod_name LIKE 'Lotta%') AS avg_04
FROM aroma.product a,
aroma.sales b,
aroma.period c,
aroma.store d
WHERE a.prodkey = b.prodkey
AND a.classkey = b.classkey
AND c.perkey = b.perkey
AND d.storekey = b.storekey
AND prod_name LIKE 'Lotta%'
AND store_name = 'San Jose Roasting Company'
AND year = 2005
AND month = 'DEC'
AND dollars <
(SELECT AVG(dollars)
FROM aroma.product a,
aroma.sales b,


aroma.period c,
aroma.store d
WHERE a.prodkey = b.prodkey
AND a.classkey = b.classkey
AND c.perkey = b.perkey
AND d.storekey = b.storekey

AND year = 2004
AND month = 'DEC'
AND store_name = 'San Jose Roasting
Company'
AND prod_name LIKE 'Lotta%');

Kết quả
PROD_NAME

STORE_NAME

DATE

SALES_05 AVG_04

Lotta Latte

San Jose Roasting Company Dec 8, 2005 153.00

154.72

Lotta Latte

San Jose Roasting Company Dec 27, 2005 144.50

154.72


So sánh bằng các truy vấn phụ của danh sách chọn lựa
Một truy vấn phụ có thể xuất hiện trong danh sách chọn lựa của một truy vấn

chính chỉ khi nó trả về một hàng hay khơng trả về hàng nào. Loại truy vấn phụ
này, gọi là truy vấn phụ vơ hướng, có ích cho các so sánh kiểu bảng tính trong đó
một loạt các giá trị được truy vấn chính trả về so sánh với một giá trị do truy vấn
phụ trả về.
Về truy vấn
Truy vấn phụ của ví dụ này trả về các số doanh thu Lotta Latte hằng ngày tại công
ty Roasting San Jose năm 2005 trong trường hợp số doanh thu đó thấp hơn số
doanh thu trung bình hàng ngày tại cùng cửa hàng trong thời gian 2004. Cột
Avg_04 có chứa chỉ một giá trị đơn lặp lại là giá trị trung bình năm 2004; giá trị
giống nhau này sẽ xuất hiện trong cột đó bất kể số lượng các hàng trong tập hợp
kết quả.
Cùng một truy vấn phụ giống như vậy xuất hiện hai lần trong truy vấn chính:


Một lần như định nghĩa cột trong danh sách lựa chọn



Một lần như một toán hạng của toán tử nhỏ hơn (<) trong một điều kiện của
mệnh đề WHERE

Truy vấn này được xử lý theo thứ tự sau:
1. Truy vấn phụ thứ hai, định nghĩa điều kiện tìm kiếm trong mệnh đề
WHERE của truy vấn chính, được thực hiện.
2. Giá trị dẫn xuất từ truy vấn phụ thứ hai được chèn vào vào trong mệnh đề
WHERE của truy vấn chính.
3. Truy vấn phụ của danh sách lựa chọn được thực hiện.
4. Truy vấn chính được thực hiện.
Các lưu ý về cách dùng
Hàm vô hướng DEC được sử dụng trên cột Avg_04 của tập kết quả để cắt bớt các

số doanh thu trung bình:


DEC(AVG(dollars),7,2)

Sử dụng các truy vấn phụ có tương quan
Câu hỏi
Doanh thu của từng sản phẩm riêng lẻ ở San Jose trong tháng Giêng 2004 so với
doanh thu hàng năm trong cùng thành phố trong cùng năm là bao nhiêu?
Ví dụ truy vấn
SELECT p1.prod_name, SUM(s1.dollars) AS jan_04_sales,
(SELECT SUM(s2.dollars)
FROM aroma.product p2,
aroma.sales s2,
aroma.period d2,
aroma.store r2
WHERE p2.prodkey = s2.prodkey
AND p2.classkey = s2.classkey
AND d2.perkey = s2.perkey
AND r2.storekey = s2.storekey
AND p1.prod_name = p2.prod_name
AND d1.year = d2.year
AND r1.city = r2.city) AS total_04_sales


FROM aroma.store r1,
aroma.sales s1,
aroma.product p1,
aroma.period d1
WHERE p1.prodkey = s1.prodkey

AND p1.classkey = s1.classkey
AND d1.perkey = s1.perkey
AND r1.storekey = s1.storekey
AND year = 2004
AND month = 'JAN'
AND city LIKE 'San J%'
GROUP BY p1.prod_name, d1.year, r1.city
ORDER BY p1.prod_name;

Kết quả
PROD_NAME

JAN_04_SALES

TOTAL_04_SALES

Aroma Roma

1653.00

21697.50

Aroma Sheffield Steel Teapot

120.00

1122.00



×