Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

NULL phức tạp - Phần 3, Thiếu các tính năng tiêu chuẩn và các lựa chọn thay thế T-SQL

Bài viết này là phần thứ ba trong loạt bài về độ phức tạp NULL. Trong Phần 1, tôi đã trình bày ý nghĩa của điểm đánh dấu NULL và cách nó hoạt động trong các phép so sánh. Trong Phần 2, tôi đã mô tả sự mâu thuẫn trong điều trị NULL trong các yếu tố ngôn ngữ khác nhau. Tháng này, tôi mô tả các tính năng xử lý NULL tiêu chuẩn mạnh mẽ vẫn chưa có trong T-SQL và các giải pháp thay thế mà mọi người hiện đang sử dụng.

Tôi sẽ tiếp tục sử dụng cơ sở dữ liệu mẫu TSQLV5 như tháng trước trong một số ví dụ của tôi. Bạn có thể tìm thấy tập lệnh tạo và điền cơ sở dữ liệu này tại đây và sơ đồ ER của nó tại đây.

Vị từ DISTINCT

Trong Phần 1 của loạt bài này, tôi đã giải thích cách NULL hoạt động trong các phép so sánh và sự phức tạp xung quanh logic vị từ ba giá trị mà SQL và T-SQL sử dụng. Hãy xem xét vị từ sau:

X =Y

Nếu bất kỳ vị từ nào là NULL - kể cả khi cả hai đều là NULL - thì kết quả của vị từ này là giá trị logic UNKNOWN. Ngoại trừ các toán tử IS NULL và IS NOT NULL, điều tương tự cũng áp dụng cho tất cả các toán tử khác, bao gồm cả khác với (<>):

X <> Y

Thông thường, trong thực tế, bạn muốn các NULL hoạt động giống như các giá trị không phải NULL cho mục đích so sánh. Đó là trường hợp đặc biệt khi bạn sử dụng chúng để đại diện cho thiếu nhưng không thể áp dụng các giá trị. Tiêu chuẩn có một giải pháp cho nhu cầu này dưới dạng một tính năng được gọi là vị từ DISTINCT, sử dụng mẫu sau:

LÀ [KHÔNG] PHÂN BIỆT TỪ

Thay vì sử dụng ngữ nghĩa bình đẳng hoặc bất bình đẳng, vị từ này sử dụng ngữ nghĩa dựa trên tính khác biệt khi so sánh các vị từ. Để thay thế cho toán tử đẳng thức (=), bạn sẽ sử dụng biểu mẫu sau để nhận giá trị TRUE khi hai vị từ giống nhau, bao gồm cả khi cả hai đều là NULL và FALSE khi chúng không phải là khác không phải:

X KHÔNG PHÂN BIỆT TỪ Y

Để thay thế cho khác với toán tử (<>), bạn sẽ sử dụng biểu mẫu sau để nhận giá trị TRUE khi hai tiên đoán khác nhau, bao gồm cả khi một là NULL và dự đoán kia thì không, và FALSE khi chúng giống nhau, bao gồm cả khi cả hai đều là NULL:

X LÀ CHIA TỪ Y

Hãy áp dụng vị từ DISTINCT cho các ví dụ mà chúng tôi đã sử dụng trong Phần 1 của loạt bài này. Nhớ lại rằng bạn cần viết một truy vấn cung cấp tham số đầu vào @dt trả về các đơn đặt hàng đã được vận chuyển vào ngày nhập nếu nó không phải là NULL hoặc hoàn toàn không được giao nếu đầu vào là NULL. Theo tiêu chuẩn, bạn sẽ sử dụng mã sau với vị từ DISTINCT để xử lý nhu cầu này:

 CHỌN orderid, ngày vận chuyển 

Bây giờ, hãy nhớ lại từ Phần 1 rằng bạn có thể sử dụng kết hợp vị từ EXISTS và toán tử INTERSECT như một giải pháp thay thế SARGable trong T-SQL, như sau:

 CHỌN orderid, ngày vận chuyển 

Để trả lại các đơn đặt hàng đã được giao vào một ngày khác với (khác với) ngày nhập @dt, bạn sẽ sử dụng truy vấn sau:

 CHỌN orderid, ngày vận chuyển 

Giải pháp thay thế hoạt động trong T-SQL sử dụng sự kết hợp của vị từ EXISTS và toán tử EXCEPT, như sau:

 CHỌN orderid, ngày giao hàng 

Trong Phần 1, tôi cũng đã thảo luận về các tình huống mà bạn cần nối các bảng và áp dụng ngữ nghĩa dựa trên tính khác biệt trong vị từ nối. Trong các ví dụ của mình, tôi đã sử dụng các bảng được gọi là T1 và T2, với các cột tham gia NULLable được gọi là k1, k2 và k3 ở cả hai phía. Theo tiêu chuẩn, bạn sẽ sử dụng mã sau để xử lý một liên kết như vậy:

 CHỌN T1.k1, T1.K2, T1.K3, T1.val1, T2.val2FROM dbo.T1INNER THAM GIA dbo.T2 TRÊN T1.k1 KHÔNG ĐƯỢC XÁC ĐỊNH TỪ T2.k1 VÀ T1.k2 KHÔNG ĐƯỢC XÁC ĐỊNH TỪ T2 .k2 VÀ T1.k3 KHÔNG ĐƯỢC Tách khỏi T2.k3; 

Hiện tại, tương tự như các tác vụ lọc trước đây, bạn có thể sử dụng kết hợp vị từ EXISTS và toán tử INTERSECT trong mệnh đề BẬT của phép nối để mô phỏng vị từ riêng biệt trong T-SQL, như sau:

 CHỌN T1.k1, T1.K2, T1.K3, T1.val1, T2.val2FROM dbo.T1INNER JOIN dbo.T2 ON EXISTS (CHỌN T1.k1, T1.k2, T1.k3 CHỌN GIAO DIỆN T2.k1 , T2.k2, T2.k3); 

Khi được sử dụng trong một bộ lọc, biểu mẫu này là SARGable và khi được sử dụng trong các phép nối, biểu mẫu này có thể dựa vào thứ tự chỉ mục.

Nếu bạn muốn thấy vị từ DISTINCT được thêm vào T-SQL, bạn có thể bỏ phiếu cho nó tại đây.

Nếu sau khi đọc phần này, bạn vẫn cảm thấy hơi băn khoăn về vị từ DISTINCT, thì bạn không đơn độc. Có lẽ vị từ này tốt hơn nhiều so với bất kỳ cách giải quyết nào hiện có mà chúng tôi hiện có trong T-SQL, nhưng nó hơi dài dòng và hơi khó hiểu. Nó sử dụng một hình thức phủ định để áp dụng những gì trong tâm trí chúng ta là một so sánh tích cực, và ngược lại. Chà, không ai nói rằng tất cả các đề xuất tiêu chuẩn là hoàn hảo. Như Charlie đã lưu ý trong một trong những nhận xét của anh ấy cho Phần 1, biểu mẫu đơn giản sau sẽ hoạt động tốt hơn:

LÀ [KHÔNG]

Nó ngắn gọn và trực quan hơn nhiều. Thay vì X KHÔNG ĐƯỢC PHÂN BIỆT TỪ Y, bạn sẽ sử dụng:

X LÀ Y

Và thay vì X LÀ CHIA TỪ Y, bạn sẽ sử dụng:

X KHÔNG PHẢI LÀ Y

Toán tử được đề xuất này thực sự phù hợp với các toán tử IS NULL và IS NOT NULL đã tồn tại.

Được áp dụng cho nhiệm vụ truy vấn của chúng tôi, để trả lại các đơn đặt hàng đã được giao vào ngày nhập (hoặc chưa được giao nếu đầu vào là NULL), bạn sẽ sử dụng mã sau:

 CHỌN orderid, ngày vận chuyểnFROM Bán hàng. Đơn hàngWHERE ngày vận chuyển LÀ @dt; 

Để trả lại các đơn đặt hàng đã được giao vào một ngày khác với ngày nhập, bạn sẽ sử dụng mã sau:

 CHỌN orderid, ngày vận chuyển 

Nếu Microsoft quyết định thêm vị từ riêng biệt, sẽ rất tốt nếu họ hỗ trợ cả dạng chi tiết tiêu chuẩn và dạng không chuẩn này nhưng ngắn gọn hơn và trực quan hơn. Thật kỳ lạ, bộ xử lý truy vấn của SQL Server đã hỗ trợ IS toán tử so sánh nội bộ, sử dụng ngữ nghĩa giống như toán tử IS mong muốn mà tôi đã mô tả ở đây. Bạn có thể tìm thông tin chi tiết về toán tử này trong bài viết của Paul White về Kế hoạch truy vấn không có giấy tờ:So sánh bình đẳng (tra cứu “IS thay vì EQ”). Điều còn thiếu là để lộ nó ra bên ngoài như một phần của T-SQL.

Điều khoản xử lý NULL (BỎ QUA NULLS | TÔN TRỌNG NULLS)

Khi sử dụng các hàm cửa sổ bù đắp LAG, LEAD, FIRST_VALUE và LAST_VALUE, đôi khi bạn cần kiểm soát hành vi xử lý NULL. Theo mặc định, các hàm này trả về kết quả của biểu thức được yêu cầu ở vị trí được yêu cầu, bất kể kết quả của biểu thức là giá trị thực hay NULL. Tuy nhiên, đôi khi bạn muốn tiếp tục di chuyển theo hướng có liên quan, (lùi đối với LAG và LAST_VALUE, chuyển tiếp đối với LEAD và FIRST_VALUE) và trả về giá trị không phải NULL đầu tiên nếu có và NULL nếu không. Tiêu chuẩn cho phép bạn kiểm soát hành vi này bằng cách sử dụng điều khoản xử lý NULL với cú pháp sau:

offset_ function () IGNORE_NULLS | TÔN TRỌNG NULLS OVER (<đặc điểm kỹ thuật cửa sổ>)

Mặc định trong trường hợp mệnh đề xử lý NULL không được chỉ định là tùy chọn RESPECT NULLS, nghĩa là trả về bất kỳ thứ gì có ở vị trí được yêu cầu ngay cả khi NULL. Thật không may, điều khoản này chưa có sẵn trong T-SQL. Tôi sẽ cung cấp các ví dụ về cú pháp chuẩn bằng cách sử dụng các hàm LAG và FIRST_VALUE, cũng như các cách giải quyết hoạt động trong T-SQL. Bạn có thể sử dụng các kỹ thuật tương tự nếu bạn cần chức năng như vậy với LEAD và LAST_VALUE.

Là dữ liệu mẫu, tôi sẽ sử dụng một bảng có tên T4 mà bạn tạo và điền bằng mã sau:

 DROP TABLE NẾU TỒN TẠI dbo.T4; ĐI TẠO BẢNG dbo.T4 (id INT NOT NULL CONSTRAINT PK_T4 PRIMARY KEY, col1 INT NULL); CHÈN VÀO CÁC GIÁ TRỊ dbo.T4 (id, col1) (2, NULL), (3, 10), (5, -1), (7, NULL), (11, NULL), (13, -12), ( 17, NULL), (19, NULL), (23, 1759); 

Có một nhiệm vụ phổ biến liên quan đến việc trả lại kết quả cuối cùng có liên quan giá trị. Giá trị NULL trong cột1 cho biết không có thay đổi nào về giá trị, trong khi giá trị không phải NULL chỉ ra một giá trị mới có liên quan. Bạn cần trả về giá trị col1 không phải NULL cuối cùng dựa trên thứ tự id. Sử dụng mệnh đề xử lý NULL tiêu chuẩn, bạn sẽ xử lý tác vụ như sau:

 CHỌN id, col1, COALESCE (col1, LAG (col1) BỎ QUA NULL (ĐẶT HÀNG THEO id)) AS lastvalFROM dbo.T4; 

Đây là kết quả mong đợi từ truy vấn này:

 id col1 lastval ----------- ----------- ----------- 2 NULL NULL3 10 105 -1-17 NULL - 111 NULL -113-12-1217 NULL -1219 NULL -1223 1759 1759 

Có một cách giải quyết khác trong T-SQL, nhưng nó liên quan đến hai lớp hàm cửa sổ và một biểu thức bảng.

Trong bước đầu tiên, bạn sử dụng hàm MAX window để tính toán một cột có tên là grp giữ giá trị id lớn nhất cho đến nay khi col1 không phải là NULL, như sau:

 CHỌN id, col1, MAX (TRƯỜNG HỢP KHI col1 KHÔNG ĐẦY ĐỦ THÌ id KẾT THÚC) HẾT (ĐẶT HÀNG THEO id ROWS UNBOUNDED PRECEDING) NHƯ grpFROM dbo.T4; 

Mã này tạo ra kết quả sau:

 id col1 grp ----------- ----------- ----------- 2 NULL NULL3 10 35 -1 57 NULL 511 NULL 513-12 1317 NULL 1319 NULL 1323 1759 23 

Như bạn có thể thấy, một giá trị grp duy nhất được tạo bất cứ khi nào có sự thay đổi trong giá trị col1.

Trong bước thứ hai, bạn xác định một CTE dựa trên truy vấn từ bước đầu tiên. Sau đó, trong truy vấn bên ngoài, bạn trả về giá trị col1 tối đa cho đến nay, trong mỗi phân vùng được xác định bởi grp. Đó là giá trị col1 không phải NULL cuối cùng. Đây là mã giải pháp hoàn chỉnh:

 WITH C AS (SELECT id, col1, MAX (TRƯỜNG HỢP KHI col1 KHÔNG ĐẦY ĐỦ THÌ id END) HẾT (ORDER BY id ROWS UNBOUNDED PRECEDING) AS grpFROM dbo.T4) CHỌN id, col1, MAX (col1) HẾT ( PHẦN THEO ĐƠN ĐẶT HÀNG CỦA grp THEO id ROWS UNBOUNDED PRECEDING) AS lastvalFROM C; 

Rõ ràng, đó là nhiều mã và hoạt động hơn rất nhiều so với việc chỉ nói IGNORE_NULLS.

Một nhu cầu phổ biến khác là trả về giá trị có liên quan đầu tiên. Trong trường hợp của chúng tôi, giả sử rằng bạn cần trả về giá trị col1 không phải NULL đầu tiên cho đến nay dựa trên thứ tự id. Sử dụng mệnh đề xử lý NULL tiêu chuẩn, bạn sẽ xử lý tác vụ với hàm FIRST_VALUE và tùy chọn BỎ QUA NULLS, như sau:

 CHỌN id, col1, FIRST_VALUE (col1) BỎ QUA HƠN NỮA (ĐẶT HÀNG THEO id ROWS UNBOUNDED PRECEDING) AS firstvalFROM dbo.T4; 

Đây là kết quả mong đợi từ truy vấn này:

 id col1 firstval ----------- ----------- ----------- 2 NULL NULL3 10 105-1 107 NULL 1011 NULL 1013-12 1017 NULL 1019 NULL 1023 1759 10 

Cách giải quyết khác trong T-SQL sử dụng kỹ thuật tương tự như kỹ thuật được sử dụng cho giá trị không phải NULL cuối cùng, chỉ thay vì phương pháp double-MAX, bạn sử dụng hàm FIRST_VALUE trên đầu hàm MIN.

Trong bước đầu tiên, bạn sử dụng hàm MIN window để tính toán một cột có tên là grp giữ giá trị id tối thiểu cho đến nay khi col1 không phải là NULL, như sau:

 CHỌN id, col1, MIN (TRƯỜNG HỢP KHI col1 KHÔNG ĐẦY ĐỦ THÌ id KẾT THÚC) HẾT (ĐẶT HÀNG THEO id ROWS UNBOUNDED PRECEDING) NHƯ grpFROM dbo.T4; 

Mã này tạo ra kết quả sau:

 id col1 grp ----------- ----------- ----------- 2 NULL NULL3 10 35 -1 37 NULL 311 NULL 313-12 317 NULL 319 KHÔNG 323 1759 3 

Nếu có bất kỳ NULL nào xuất hiện trước giá trị liên quan đầu tiên, bạn sẽ có hai nhóm — nhóm đầu tiên có NULL làm giá trị grp và nhóm thứ hai có id không phải NULL đầu tiên làm giá trị grp.

Trong bước thứ hai, bạn đặt mã của bước đầu tiên trong biểu thức bảng. Sau đó, trong truy vấn bên ngoài, bạn sử dụng hàm FIRST_VALUE, được phân vùng bởi grp, để thu thập giá trị có liên quan (không phải NULL) đầu tiên nếu có và NULL nếu không, như sau:

 WITH C AS (SELECT id, col1, MIN (TRƯỜNG HỢP KHI col1 KHÔNG ĐẦY ĐỦ THÌ id END) OVER (ORDER BY id ROWS UNBOUNDED PRECEDING) AS grpFROM dbo.T4) SELECT id, col1, FIRST_VALUE (col1) OVER ( PHẦN THEO ĐƠN ĐẶT HÀNG grp THEO id ROWS UNBOUNDED PRECEDING) AS firstvalFROM C; 

Một lần nữa, đó là rất nhiều mã và hiệu quả so với việc chỉ sử dụng tùy chọn IGNORE_NULLS.

Nếu bạn cảm thấy rằng tính năng này có thể hữu ích cho mình, bạn có thể bỏ phiếu cho việc đưa nó vào T-SQL tại đây.

ĐẶT HÀNG BẰNG NULLS ĐẦU TIÊN | NULLS CUỐI CÙNG

Khi bạn sắp xếp dữ liệu, cho dù cho mục đích trình bày, cửa sổ, lọc TOP / OFFSET-FETCH hay bất kỳ mục đích nào khác, bạn có câu hỏi là NULLs sẽ hoạt động như thế nào trong ngữ cảnh này? Tiêu chuẩn SQL nói rằng các NULL nên sắp xếp cùng nhau trước hoặc sau không phải NULL, và chúng để việc triển khai xác định theo cách này hay cách khác. Tuy nhiên, bất cứ điều gì nhà cung cấp chọn, nó cần phải nhất quán. Trong T-SQL, NULL được sắp xếp đầu tiên (trước không phải NULL) khi sử dụng thứ tự tăng dần. Hãy xem xét truy vấn sau đây làm ví dụ:

 CHỌN orderid, ngày vận chuyểnFROM Bán hàng.OrdersORDER THEO ngày vận chuyển, orderid; 

Truy vấn này tạo ra kết quả sau:

 orderid ngày vận chuyển ----------- ----------- 11008 NULL11019 NULL11039 NULL ... 10249 2017-07-1010252 2017-07-1110250 2017-07-12 ... 11063 2019-05-0611067 2019-05-0611069 2019-05-06 

Kết quả hiển thị rằng các đơn hàng chưa được vận chuyển, có ngày vận chuyển NULL, đơn đặt hàng trước các đơn hàng được vận chuyển, có ngày vận chuyển hiện có áp dụng.

Nhưng nếu bạn cần NULL để xếp thứ tự cuối cùng khi sử dụng thứ tự tăng dần thì sao? Tiêu chuẩn ISO / IEC SQL hỗ trợ một mệnh đề mà bạn áp dụng cho một biểu thức sắp xếp kiểm soát xem thứ tự NULLs đầu tiên hay cuối cùng. Cú pháp của mệnh đề này là:

NULLS FIRST | NULLS CUỐI

Để xử lý nhu cầu của chúng tôi, trả lại các đơn đặt hàng được sắp xếp theo ngày vận chuyển của chúng, tăng dần, nhưng với các đơn hàng chưa vận chuyển được trả lại sau cùng và sau đó theo ID đơn đặt hàng của họ như một mã buộc, bạn sẽ sử dụng mã sau:

 CHỌN orderid, ngày vận chuyểnFROM Bán hàng.OrdersORDER THEO ngày vận chuyển NULLS CUỐI, orderid; 

Rất tiếc, điều khoản đặt hàng NULLS này không có sẵn trong T-SQL.

Một cách giải quyết phổ biến mà mọi người sử dụng trong T-SQL là đặt trước biểu thức sắp xếp bằng biểu thức CASE trả về một hằng số có giá trị thứ tự thấp hơn cho các giá trị không phải NULL so với NULL, như vậy (chúng tôi sẽ gọi giải pháp này là Truy vấn 1):

 CHỌN orderid, ngày vận chuyểnFROM Sales.OrdersORDER THEO TRƯỜNG HỢP KHI ngày vận chuyển KHÔNG ĐẦY ĐỦ THÌ 0 HẾT 1 KẾT THÚC, ngày vận chuyển, orderid; 

Truy vấn này tạo ra kết quả mong muốn với các NULL hiển thị sau cùng:

 orderid ngày vận chuyển ----------- ----------- 10249 2017-07-1010252 2017-07-1110250 2017-07-12 ... 11063 2019-05 -0611067 2019-05-0611069 2019-05-0611008 NULL11019 NULL11039 NULL ... 

Có một chỉ mục bao gồm được xác định trên bảng Sales.Orders, với cột ngày vận chuyển là khóa. Tuy nhiên, tương tự như cách cột lọc thao tác ngăn cản khả năng SARG của bộ lọc và khả năng áp dụng chỉ mục tìm kiếm, cột sắp xếp bị thao tác ngăn khả năng dựa vào thứ tự chỉ mục để hỗ trợ mệnh đề ORDER BY của truy vấn. Do đó, SQL Server tạo một kế hoạch cho Truy vấn 1 với một toán tử Sắp xếp rõ ràng, như thể hiện trong Hình 1.

Hình 1:Kế hoạch cho Truy vấn 1

Đôi khi kích thước của dữ liệu không lớn đến mức khiến cho việc sắp xếp rõ ràng là một vấn đề. Nhưng đôi khi nó là như vậy. Với việc sắp xếp rõ ràng, khả năng mở rộng của truy vấn trở nên siêu tuyến tính (bạn trả nhiều tiền hơn cho mỗi hàng nếu bạn có nhiều hàng hơn) và thời gian phản hồi (thời gian hàng đầu tiên được trả lại) bị trễ.

Có một thủ thuật mà bạn có thể sử dụng để tránh sắp xếp rõ ràng trong trường hợp như vậy với một giải pháp được tối ưu hóa bằng cách sử dụng toán tử Kết hợp Nối kết nối duy trì thứ tự. Bạn có thể tìm thấy một phạm vi chi tiết của kỹ thuật này được sử dụng trong các trường hợp khác nhau trong SQL Server:Tránh sắp xếp với kết hợp kết hợp nối. Bước đầu tiên trong giải pháp hợp nhất kết quả của hai truy vấn:một truy vấn trả về các hàng mà cột sắp xếp không phải là NULL với một cột kết quả (chúng tôi sẽ gọi nó là sortcol) dựa trên một hằng số với một số giá trị sắp xếp, chẳng hạn như 0, và một truy vấn khác trả về các hàng có NULL, với sortcol được đặt thành một hằng số có giá trị thứ tự cao hơn trong truy vấn đầu tiên, chẳng hạn như 1. Trong bước thứ hai, sau đó bạn xác định biểu thức bảng dựa trên mã từ bước đầu tiên, sau đó trong truy vấn bên ngoài, bạn sắp xếp thứ tự các hàng từ biểu thức bảng trước tiên theo sortcol, sau đó theo thứ tự các phần tử còn lại. Đây là mã hoàn chỉnh của giải pháp triển khai kỹ thuật này (chúng tôi sẽ gọi giải pháp này là Truy vấn 2):

 VỚI C AS (CHỌN orderid, ngày vận chuyển, 0 AS sortcolFROM Bán hàng. Đơn hàngWHERE ngày vận chuyển KHÔNG PHẢI LÀ NULL UNION TẤT CẢ CHỌN orderid, ngày vận chuyển, 1 AS sortcolFROM Bán hàng. Đơn hàng; 

Kế hoạch cho truy vấn này được thể hiện trong Hình 2.

Hình 2:Kế hoạch cho Truy vấn 2

Lưu ý hai tìm kiếm và quét phạm vi theo thứ tự trong chỉ mục bao gồm idx_nc_shippeddate — một kéo các hàng có ngày vận chuyển không phải là NULL và một kéo các hàng khác có ngày vận chuyển là NULL. Sau đó, tương tự như cách thuật toán Merge Join hoạt động trong một phép nối, thuật toán Merge Join (Ghép nối) hợp nhất các hàng từ hai phía được sắp xếp theo cách giống như dây kéo và duy trì thứ tự đã nhập để hỗ trợ nhu cầu sắp xếp trình bày của truy vấn. Tôi không nói rằng kỹ thuật này luôn nhanh hơn giải pháp điển hình hơn với biểu thức CASE, sử dụng tính năng sắp xếp rõ ràng. Tuy nhiên, cái trước có tỷ lệ tuyến tính và cái sau có tỷ lệ n log n. Vì vậy, hàng trước sẽ có xu hướng hoạt động tốt hơn với số lượng hàng lớn và hàng sau với số lượng nhỏ.

Rõ ràng là rất tốt nếu có một giải pháp cho nhu cầu chung này, nhưng sẽ tốt hơn nhiều nếu T-SQL bổ sung hỗ trợ cho mệnh đề đặt hàng NULL tiêu chuẩn trong tương lai.

Kết luận

Tiêu chuẩn ISO / IEC SQL có khá nhiều tính năng xử lý NULL mà vẫn chưa có trong T-SQL. Trong bài viết này, tôi đã đề cập đến một số trong số chúng:vị từ DISTINCT, mệnh đề điều trị NULL và kiểm soát xem thứ tự NULLs đầu tiên hay cuối cùng. Tôi cũng đã cung cấp các giải pháp thay thế cho các tính năng này được hỗ trợ trong T-SQL, nhưng chúng rõ ràng là cồng kềnh. Tháng tới, tôi tiếp tục thảo luận bằng cách đề cập đến ràng buộc duy nhất tiêu chuẩn, nó khác với cách triển khai T-SQL như thế nào và các giải pháp thay thế có thể được triển khai trong T-SQL.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nhiều cách để xóa bản sao khỏi bảng SQL

  2. Cách cài đặt Apache Cassandra trên Ubuntu 20.10 / Ubuntu 20.04

  3. ODBC 4.0

  4. Kết nối MS SQL với IRI Workbench

  5. Zombie PerfMon đếm không bao giờ chết!