Biểu thức giá trị

Một phần của tài liệu Tài liệu quản trị postgresql (Trang 58 - 69)

Các biểu thức giá trị sẽ được sử dụng trong các ngữ cảnh khác nhau, như trong danh sách đích của lệnh SELECT, khi các giá trị cột mới trong INSERT hoặc UPDATE hoặc trong các điều kiện trong một số lệnh. Kết quả của một biểu thức giá trị đôi khi được gọi là một lượng vô hướng, để phân biệt nó với kết quả của một biểu thức bảng (nó là một bảng). Các biểu thức giá trị vì thế cũng được gọi là các biểu thức vô hướng (hoặc thậm chí đơn giản là các biểu thức). Cú pháp của biểu thức cho phép tính toán các giá trị từ các phần nguyên sơ bằng việc sử dụng tính toán số học, logic, tập hợp và các hoạt động khác.

Một biểu thức giá trị là một biểu thức dạng sau đây:

• Một giá trị hằng

• Một tham chiếu cột

• Một tham chiếu tham số vị trí, trong thân của định nghĩa hàm hoặc khai báo được chuẩn bị

• Một biểu thức có đánh chỉ số dưới

• Một biểu thức lựa chọn trường

• Một viện dẫn toán tử

• Một lời gọi hàm

• Một biểu thức tổng hợp

• Một lời gọi hàm cửa sổ

• Một dạng phát hành cast

• Một truy vấn con vô hướng

• Một cấu trúc mảng

• Một cấu trúc hàng

• Biểu thức giá trị khác trong các dấu ngoặc đơn (được sử dụng để tạo nhóm các biểu thức con và ghi đè ưu tiên trước)

Bổ sung vào danh sách này, có một số cấu trúc mà có thể được phân loại như một biểu thức nhưng không tuân theo bất kỳ qui tắc cú pháp chung nào. Chúng thường có ngữ nghĩa của một hàm hoặc toán tử và được giải thích ở vị trí phù hợp trong Chương 9. Một ví dụ là mệnh đề IS NULL.

Chúng ta đã thảo luận các hằng trong Phần 4.1.2. Các phần sau đây thảo luận các lựa chọn còn lại.

4.2.1. Các tham chiếu cột Một cột có thể được tham chiếu ở dạng:

correlation.columnname

correlation là tên của một bảng (có khả năng đủ điều kiện với một tên sơ đồ), hoặc một tên hiệu (alias) đối với một bảng được xác định bằng một mệnh đề FROM. Tên correlation và dấu chấm có thể được bỏ qua nếu tên cột là duy nhất xuyên tất cả các bảng đang được sử dụng trong truy vấn hiện hành. (Xem thêm Chương 7).

4.2.2. Tham số vị trí

Một tham chiếu tham số vị trí được sử dụng để chi ra một giá trị được cung cấp từ bên ngoài cho một lệnh SQL. Các tham số được sử dụng trong các định nghĩa hàm SQL và trong các truy vấn được chuẩn bị. Một số thư viện máy trạm cũng hỗ trợ việc chỉ định các giá trị dữ liệu tách biệt khỏi chuỗi lệnh SQL, trong trường hợp đó các tham số được sử dụng để tham chiếu tới các giá trị dữ liệu nằm ngoài dòng. Mẫu của một tham chiếu tham số là:

$number

Ví dụ, hãy xem xét định nghĩa của một hàm, dept, như:

CREATE FUNCTION dept(text) RETURNS dept

AS $$ SELECT * FROM dept WHERE name = $1 $$

LANGUAGE SQL;

Ở đây $1 tham chiếu tới giá trị của đối số hàm đầu tiên bất kỳ khi nào hàm đó được gọi.

4.2.3. Chỉ số dưới - Subscript

Nếu một biểu thức có một giá trị ở dạng mảng, thì một phần tử đặc thù của giá trị mảng đó có thể được trích xuất bằng việc viết

expression[subscript]

hoặc nhiều phần tử liền kề (một “lát cắt mảng”) có thể được trích xuất bằng việc viết

expression[lower_subscript:upper_subscript]

(Ở đây, các dấu ngoặc vuông [ ] có nghĩa là sẽ xuất hiện theo nghĩa đen). Mỗi subscript bản thân nó là một biểu thức, nó phải có một giá trị nguyên.

Nói chung biểu thức mảng phải nằm trong các dấu ngoặc đơn, nhưng các dấu ngoặc đơn có thể bị bỏ qua khi biểu thức đó sẽ được viết theo chỉ số dưới chỉ là một tham chiếu cột hoặc tham số vị trí.

Hơn nữa, nhiều chỉ số dưới có thể được ghép khi mảng gốc ban đầu là đa chiều. Ví dụ:

mytable.arraycolumn[4]

mytable.two_d_column[17][34]

$1[10:42]

(arrayfunction(a,b))[42]

Các dấu ngoặc đơn trong ví dụ cuối được yêu cầu. Xem phần 8.14 để biết thêm về các mảng.

4.2.4. Chọn trường

Nếu một biểu thức có một giá trị ở dạng tổng hợp (dạng hàng), thì một trường đặc biệt của hàng đó có thể được trích xuất bằng cách viết

expression.fieldname

Nói chung biểu thức hàng phải nằm trong các dấu ngoặc đơn, nhưng các dấu ngoặc đơn có thể bị bỏ qua khi biểu thức đó được chọn từ chỉ một tham chiếu bảng hoặc tham số vị trí. Ví dụ:

mytable.mycolumn

$1.somecolumn (rowfunction(a,b)).col3

(Vì thế, một tham chiếu cột đủ tiêu chuẩn thực sự chỉ là một trường hợp đặc biệt của cú pháp chọn trường). Một trường hợp đặc biệt quan trọng là việc trích xuất một trường từ một cột của bảng ở dạng tổng hợp:

(compositecol).somefield

(mytable.compositecol).somefield

Các dấu ngoặc đơn được yêu cầu ở đây để chỉ ra rằng compositecol là một tên cột chứ không phải là tên bảng, hoặc rằng mytable là một tên bảng chứ không phải là tên sơ đồ trong trường hợp thứ 2.

4.2.5. Viện dẫn toán tử

Có 3 khả năng cú pháp cho một sự viện dẫn toán tử:

expression operator expression (toán tử trung tố nhị phân)

operator expression (toán tử tiền tố một toán hạng)

expression operator (toán tử hậu tố một toán hạng)

trong đó thẻ toán tử operator đi sau các qui tắc cú pháp của Phần 4.1.3, hoặc là một trong những từ khóa AND, OR, và NOT, hoặc là một tên toán tử đủ điều kiện ở dạng:

OPERATOR(schema.operatorname)

Những toán tử đặc biệt nào tồn tại và liệu chúng có là một toán hạng hay nhị phân sẽ phụ thuộc vào các toán tử nào từng được hệ thống hoặc người sử dụng định nghĩa. Chương 9 mô tả các toán tử được xây dựng sẵn.

4.2.6. Lời gọi hàm

Cú pháp một lời gọi hàm là tên của hàm (có thể đủ điều kiện với một tên sơ đồ), theo sau là danh sách các đối số được đưa vào trong các dấu ngoặc đơn:

function_name ([expression [, expression ... ]] )

Ví dụ, thứ sau đây tính toán căn bậc 2:

sqrt(2)

Danh sách các hàm xây dựng sẵn là trong Chương 9. Các hàm khác có thể được người sử dụng bổ sung thêm. Các đối số có thể có các tên được tùy ý gắn vào. Xem Phần 4.3 để có thêm các chi tiết.

4.2.7. Biểu thức tổng hợp

Một biểu thức tổng hợp đại diện cho ứng dụng của một hàm tổng hợp khắp các hàng được một truy vấn lựa chọn. Một hàm tổng hợp làm giảm nhiều đầu vào tới một giá trị đầu vào duy nhất, như tổng hoặc trung bình các đầu vào. Cú pháp của một biểu thức tổng hợp là một trong những thứ sau:

aggregate_name (expression [ , ... ] [ order_by_clause ] ) aggregate_name (ALL expression [ , ... ] [ order_by_clause ] ) aggregate_name (DISTINCT expression [ , ... ] [ order_by_clause ] ) aggregate_name ( * )

trong đó aggregate_name là một tổng hợp được định nghĩa trước (có khả năng đủ điều kiện với một tên sơ đồ), expression là bất kỳ biểu thức nào mà bản thân nó không chứa một biểu thức tổng hợp hoặc một lời gọi hàm cửa sổ, và order_by_clause là một mệnh đề ORDER BY tùy chọn như được mô tả bên dưới.

Mẫu ban đầu của biểu thức tổng hợp gọi sự tổng hợp một lần cho từng hàng đầu vào. Mẫu thứ 2 là y hệt như mẫu đầu, vì ALL là mặc định. Mẫu thứ 3 gọi tổng hợp một lần cho từng giá trị duy nhất của biểu thức (hoặc tập hợp duy nhất các giá trị, cho nhiều biểu thức) được thấy trong các hàng đầu vào. Mẫu cuối cùng gọi tổng hợp một lần cho từng hàng đầu vào; vì không có giá trị đầu vào cụ thể nào được chỉ định, nó thường chỉ hữu dụng cho hàm tổng hợp đếm count(*).

Hầu hết các hàm tổng hợp bỏ qua các đầu vào null, nên các hàng trong đó một hoặc nhiều biểu thức hơn có null sẽ bị bỏ qua. Điều này có thể được giả thiết là đúng, trừ phi điều khác được chỉ định, cho tất cả các tổng hợp được xây dựng sẵn.

Ví dụ, count(*) cho tổng số các hàng đầu vào; count(f1) cho số các hàng đầu vào theo đó f1 không là null, vì count bỏ qua null; và count(distinct f1) cho số các giá trị duy nhất không là null của f1.

Thông thường, các hàng đầu vào được nuôi dưỡng cho hàm tổng hợp theo một trật tự không được chỉ định trước. Trong nhiều trường hợp điều này không là vấn đề; ví dụ, min tạo ra kết quả y hệt bất kể trật tự nào nó nhận được các đầu vào. Tuy nhiên, một số hàm tổng hợp (như array_agg và

string_agg) tạo ra các kết quả phụ thuộc vào thứ tự các hàng đầu vào. Khi sử dụng một tổng hợp như vậy, tùy chọn order_by_clause có thể được sử dụng để chỉ định trật tự mong muốn. Tùy chọn

order_by_clause có cú pháp y hệt như đối với một mệnh đề mức truy vấn ORDER BY, như được mô tả trong Phần 7.5, ngoại trừ là các biểu thức của nó luôn chỉ là các biểu thức và không thể là các tên

cột đầu ra hoặc các con số. Ví dụ:

SELECT array_agg(a ORDER BY b DESC) FROM table;

Khi làm việc với nhiều hàm tổng hợp nhiều đối số, lưu ý là mệnh đề ORDER BY đi sau tất cả các đối số tổng hợp. Ví dụ, hãy viết thế này:

SELECT string_agg(a, ’,’ ORDER BY a) FROM table;

không viết thế này:

SELECT string_agg(a ORDER BY a, ’,’) FROM table; -- incorrect

Cái sau là đúng về cú pháp, nhưng nó thể hiện một lời gọi của một hàm tổng hợp một đối số duy nhất với 2 khóa ORDER BY (khóa thứ 2 khá là vô dụng vì nó là một hằng).

Nếu DISTINCT được chỉ định thêm vào một tùy chọn order_by_clause, thì tất cả các biểu thức ORDER BY phải khớp với các đối số thông thường của tổng hợp đó; đó là, bạn không thể sắp xếp trong một biểu thức mà không được đưa vào trong danh sách DISTINCT.

Lưu ý: Khả năng để chỉ định cả DISTINCT và ORDER BY trong một hàm tổng hợp là một mở rộng của PostgreSQL.

Các hàm tổng hợp được xác định trước được mô tả trong Phần 9.18. Các hàm tổng hợp khác có thể được người sử dụng bổ sung thêm vào.

Một biểu thức tổng hợp chỉ có thể xuất hiện trong danh sách kết quả hoặc mệnh đề HAVING của một lệnh SELECT. Là cấm kỵ trong các mệnh đề khác, như WHERE, vì các mệnh đề đó được đánh giá về logic trước khi các kết quả của các tổng hợp được hình thành.

Khi một biểu thức tổng hợp xuất hiện trong một truy vấn con (xem Phần 4.2.10 và Phần 9.20), thì tổng hợp đó thường được đánh giá đối với các hàng của truy vấn phụ đó. Nhưng một ngoại lệ xảy ra nếu các đối số của tổng hợp đó chỉ có các biến mức vòng ngoài: thì tổng hợp đó sau đó thuộc về mức vòng ngoài gần nhất, và được đánh giá đối với các hàng của truy vấn đó. Biểu thức tổng hợp như một tổng thể sau đó là một tham chiếu vòng ngoài cho truy vấn con mà nó xuất hiện trong đó, và hành động như một hằng đối với bất kỳ sự đánh giá nào đối với truy vấn con đó. Hạn chế về việc xuất hiện này chỉ trong danh sách kết quả hoặc mệnh đề HAVING áp dụng với lưu ý đối với mức truy vấn mà tổng hợp đó thuộc về.

4.2.8. Lời gọi hàm cửa sổ

Một lời gọi hàm cửa sổ đại diện cho ứng dụng của một hàm dạng tổng hợp đối với một số phần của các hàng được một truy vấn lựa chọn. Không giống như các lời gọi hàm tổng hợp thông thường, điều này không bị trói vào việc tạo nhóm các hàng được lựa chọn vào một hàng đầu ra duy nhất - từng hàng vẫn giữ là tách biệt nhau ở đầu ra của truy vấn. Tuy nhiên hàm cửa sổ có khả năng quét tất cả các hàng mà có thể là một phần của nhóm các hàng hiện hành mà tuân theo đặc tả tạo thành nhóm (danh sách PARTITION BY) của lời gọi hàm cửa sổ. Cú pháp của một lời gọi hàm cửa sổ là cú pháp như sau:

function_name ([expression [, expression ... ]]) OVER ( window_definition ) function_name ([expression [, expression ... ]]) OVER window_name function_name ( * ) OVER ( window_definition )

function_name ( * ) OVER window_name

trong đó window_definition có cú pháp:

[ existing_window_name ] [ PARTITION BY expression [, ...] ]

[ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] [ frame_clause ]

và tùy chọn frame_clause có thể là một trong số

[ RANGE | ROWS ] frame_start

[ RANGE | ROWS ] BETWEEN frame_start AND frame_end

trong đó frame_start và frame_end có thể là một trong số

UNBOUNDED PRECEDING value PRECEDING

CURRENT ROW value FOLLOWING

UNBOUNDED FOLLOWING

Ở đây biểu thức - expression thể hiện bất kỳ biểu thức giá trị nào mà bản thân nó không có các lời gọi hàm cửa sổ. Các danh sách PARTITION BY và ORDER BY về cơ bản có cùng cú pháp và ngữ nghĩa y hệt như các mệnh đề GROUP BY và ORDER BY của toàn bộ truy vấn, ngoại trừ là các biểu thức của chúng luôn chỉ là các biểu thức và không thể là các tên cột đầu ra hoặc các con số. window_name là một tham chiếu tới một đặc tả cửa sổ được đặt tên được xác định trong mệnh đề WINDOW của truy vấn. Các đặc tả cửa sổ được đặt tên thường được tham chiếu với chỉ OVER window_name, nhưng nó cũng có khả năng để viết tên một cửa sổ vào trong các dấu ngoặc đơn và sau đó cung cấp tùy ý cho một mệnh đề sắp xếp và/hoặc mệnh đề khung (cửa sổ được tham chiếu phải không có các mệnh đề đó, nếu chúng được cung cấp ở đây). Cú pháp sau ở đây tuân theo cùng các qui tắc y hệt như việc sửa đổi tên của một cửa sổ đang tồn tại bên trong mệnh đề WINDOW; xem trang tham chiếu SELECT

để có thêm các chi tiết.

frame_clause chỉ định tập hợp các hàng tạo thành khung cửa sổ, đối với các hàm cửa sổ mà hành động trong khung (frame) thay vì toàn bộ phân vùng. Nếu frame_end bị bỏ qua thì các mặc định là cho hàng hiện hành CURRENT ROW. Những hạn chế là việc frame_start không thể là tuân theo vô giới hạn UNBOUNDED FOLLOWING, frame_end không thể là có trước không giới hạn UNBOUNDED PRECEDING, và lựa chọn frame_end không thể xuất hiện sớm hơn trong danh sách ở trên so với lựa chọn frame_start - ví dụ RANGE BETWEEN CURRENT ROW AND value PRECEDING là không được phép.

Tùy chọn tạo khung mặc định là RANGE UNBOUNDED PRECEDING, nó là y hệt như RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW; nó thiết lập khung để tất cả các hàng từ phân vùng đó khởi tạo qua điểm ngang hàng cuối cùng của hàng hiện hành trong trật tự ORDER BY (nó có nghĩa là tất cả các hàng nếu không có ORDER BY). Nói chung, UNBOUNDED PRECEDING có nghĩa là khung đó bắt đầu với hàng đầu tiên của phân vùng, và tương tự UNBOUNDED FOLLOWING có nghĩa là khung kết thúc với hàng cuối cùng của phân vùng (bất kể chế độ RANGE hay ROWS). Trong chế độ ROWS,

CURRENT ROW có nghĩa là khung bắt đầu hoặc kết thúc với hàng hiện hành; nhưng trong chế độ

RANGE thì nó có nghĩa là khung bắt đầu và kết thúc với điểm ngang hàng đầu tiên hoặc cuối cùng

của hàng hiện hành theo trật tự ORDER BY. Các trường hợp giá trị PRECEDING và giá trị FOLLOWING

hiện chỉ được phép trong chế độ ROWS. Chúng chi ra rằng khung bắt đầu hoặc kết thúc với hàng mà có nhiều hàng trước hoặc sau hàng hiện hành. Giá trị value phải là một biểu thức số nguyên không chứa bất kỳ biến, các hàm tổng hợp hoặc các hàm cửa sổ nào. Giá trị đó phải không là null hoặc âm;

nhưng nó có thể là 0, khi chọn bản thân hàng hiện hành.

Các hàm cửa sổ được xây dựng sẵn được mô tả trong Bảng 9-44. Các hàm cửa sổ khác có thể được người sử dụng cho thêm vào. Hơn nữa, bất kỳ hàm tổng hợp được xây dựng sẵn hay do người sử dụng định nghĩa cũng có thể được sử dụng như một hàm cửa sổ.

Các cú pháp sử dụng dấu * được sử dụng để gọi các hàm tổng hợp ít tham số như các hàm cửa sổ, ví dụ count(*) OVER (PARTITION BY x ORDER BY y). * không được sử dụng một cách thông thường cho các hàm cửa sổ không tổng hợp. Các hàm cửa sổ tổng hợp, không giống như các hàm tổng hợp, không cho phép DISTINCT hoặc ORDER BY được sử dụng bên trong danh sách đối số hàm.

Các lời gọi hàm cửa sổ chỉ được phép trong danh sách SELECT và mệnh đề ORDER BY của truy vấn.

Nhiều thông tin hơn về các hàm cửa sổ có thể thấy trong Phần 3.5, Phần 9.19 và Phần 7.2.4.

4.2.9. Cast dạng

Một cast dạng chỉ định một sự chuyển đổi từ dạng dữ liệu này sang dạng dữ liệu khác. PostgreSQL chấp nhận 2 cú pháp tương đương nhau cho các cast dạng:

CAST ( expression AS type ) expression::type

Cú pháp của CAST tuân thủ SQL; cú pháp với :: là sử dụng theo lịch sử của PostgreSQL.

Khi một cast được áp dụng cho một biểu thức giá trị của một dạng được biết, nó thể hiện một biến đổi dạng thời gian thực. Cast sẽ chỉ thành công nếu một hoạt động biến đổi dạng phù hợp từng được xác định. Lưu ý điều này là hơi khác với sử dụng các cast với các hằng, được chỉ ra ở Phần 4.1.2.7.

Một cast được áp dụng cho một hằng chuỗi để tự nhiên thể hiện sự chỉ định trong nội bộ một dạng đối với giá trị hằng theo nghĩa đen, và vì thế nó sẽ thành công đối với bất kỳ dạng nào (nếu các nội dung của hằng chuỗi là cú pháp đầu vào chấp nhận được cho dạng dữ liệu đó).

Một cast dạng rõ ràng có thể thường được làm mờ đi nếu không có sự mù mờ như đối với dạng mà một biểu thức giá trị phải sinh ra (ví dụ, khi nó được chỉ định tới một cột của bảng); hệ thống sẽ tự động áp dụng một cast dạng trong các trường hợp như vậy. Tuy nhiên, việc cast tự động chỉ được thực hiện cho các cast được đánh dấu “OK to apply implicitly” (“OK để áp dụng một cách ẩn”) trong các catalog hệ thống. Các cast khác phải được gọi với cú pháp của việc cast rõ ràng. Hạn chế này được mong đợi để ngăn chặn sự biến đổi gây ngạc nhiên khi được áp dụng một cách âm thầm.

Cũng có khả năng để chỉ định một cast dạng bằng việc sử dụng một cú pháp giống hàm:

typename ( expression )

Tuy nhiên, điều này chỉ làm việc cho các dạng mà các tên của chúng cũng là hợp lệ như các tên

Một phần của tài liệu Tài liệu quản trị postgresql (Trang 58 - 69)

Tải bản đầy đủ (PDF)

(372 trang)