Bản cập nhật 2021-09-17 :Kể từ hôm nay, gerardnll cung cấp câu trả lời tốt hơn (IMO tốt nhất) :
Để giúp mọi người tìm ra giải pháp sạch sẽ nhất, tôi khuyên bạn nên ủng hộ câu trả lời của gerardnll .
(FYI, tôi cũng chính là người đã đặt câu hỏi ban đầu.)
Đây là câu trả lời ban đầu của tôi từ năm 2013
Đây là giải pháp hai cột thanh lịch theo ràng buộc "- một hoặc cột khác không rỗng "Bảng tin PostgreSQL :
ALTER TABLE my_table ADD CONSTRAINT my_constraint CHECK (
(column_1 IS NULL) != (column_2 IS NULL));
(Nhưng cách tiếp cận trên không thể khái quát cho ba cột trở lên.)
Nếu bạn có ba cột trở lên, bạn có thể sử dụng phương pháp tiếp cận bảng sự thật được minh họa bởi a_horse_with_no_name . Tuy nhiên, tôi cho rằng những điều sau đây sẽ dễ duy trì hơn vì bạn không phải nhập các kết hợp hợp lý:
ALTER TABLE my_table
ADD CONSTRAINT my_constraint CHECK (
(CASE WHEN column_1 IS NULL THEN 0 ELSE 1 END) +
(CASE WHEN column_2 IS NULL THEN 0 ELSE 1 END) +
(CASE WHEN column_3 IS NULL THEN 0 ELSE 1 END) = 1;
Để thu gọn điều này, sẽ hữu ích khi tạo một hàm tùy chỉnh để CASE WHEN column_k IS NULL THEN 0 ELSE 1 END
boilerplate có thể bị xóa, để lại một cái gì đó như:
(non_null_count(column_1) +
non_null_count(column_2) +
non_null_count(column_3)) = 1
Điều đó có thể nhỏ gọn như PSQL sẽ cho phép (?). Điều đó nói rằng, tôi muốn sử dụng loại cú pháp này nếu có thể:
non_null_count(column_1, column_2, column_3) = 1