Rà soát pull request SQL bằng AI để chặn lỗi JOIN, NULL và lọc ngày
Đừng để AI viết SQL rồi merge ngay. Hãy dùng AI như reviewer thứ hai để soi nguy cơ JOIN nhân dòng, hành vi NULL và các giả định trong điều kiện ngày, rồi xác minh bằng fixture nhỏ trước khi dashboard nhận số mới.
Một pull request sửa dashboard có thể chỉ thêm một JOIN, nhưng doanh thu trên Power BI, Looker hay Metabase bỗng tăng bất thường. Lỗi không nhất thiết nằm ở công thức tổng: một dòng ở bảng fact có thể ghép với nhiều dòng ở bảng bên phải, làm giá trị bị lặp trước khi SUM() chạy.
AI có thể giúp đọc PR nhanh hơn, nhưng không nên là người phê duyệt cuối cùng. Vai trò hữu ích hơn là reviewer thứ hai: buộc người viết SQL nêu rõ “một dòng là gì”, chỉ ra giả định chưa được chứng minh về JOIN, và đề xuất ca kiểm tra cho NULL cùng ranh giới ngày.
Với analyst và BI developer, đây là lớp rà soát cần thiết khi một query phục vụ nhiều dashboard, báo cáo Excel hoặc pipeline pandas. SQL cần không chỉ “chạy được”, mà còn giữ số liệu đúng sau khi merge.
Ba điểm AI cần soi trong PR SQL
Trong PostgreSQL, phần FROM tạo ra một bảng trung gian. WHERE, GROUP BY và HAVING tiếp tục biến đổi bảng đó trước khi SELECT tạo kết quả. Vì vậy, sai lệch có thể bắt đầu từ FROM hoặc JOIN; biểu đồ chỉ là nơi nó lộ ra.
1. JOIN có thể nhân dòng
Với INNER JOIN, mỗi dòng ở bảng trái tạo một dòng kết quả cho mỗi dòng ở bảng phải thỏa điều kiện nối. Nếu một khóa nối xuất hiện nhiều lần ở bảng phải, một giao dịch có thể xuất hiện nhiều lần trong kết quả.
AI cần nêu rõ đây là rủi ro cần kiểm tra, thay vì tự suy luận rằng một cột như customerid chắc chắn là duy nhất.
2. NULL sau outer join
LEFT JOIN giữ lại mọi dòng từ bảng bên trái. Khi không có dòng khớp ở bảng bên phải, các cột từ bảng bên phải sẽ là NULL.
Đó có thể là hành vi mong muốn, hoặc là tín hiệu cho thấy dữ liệu dimension đang thiếu. PR cần nói rõ dashboard phải hiển thị NULL, giá trị thay thế, hay cần đánh dấu lỗi dữ liệu.
3. Điều kiện ngày cần có quy ước nghiệp vụ
AI không thể tự biết cột nào là mốc thời gian đúng cho báo cáo, ngày cuối có bao gồm hay không, hay dữ liệu có phần thời gian trong ngày không.
Tài liệu PostgreSQL về biểu thức bảng và JOIN không đưa ra một công thức lọc ngày chuẩn cho mọi tình huống. Vì vậy, hãy yêu cầu tác giả PR ghi rõ quy ước ngày trước khi AI nhận xét logic.
> AI không thể xác nhận một khóa là duy nhất chỉ từ tên cột. Hãy cung cấp grain, ràng buộc khóa và dữ liệu mẫu đã được che thông tin nhạy cảm.
Quy trình dùng AI như reviewer thứ hai
1. Gửi “hợp đồng dữ liệu”, không chỉ gửi SQL
Trước khi dán diff vào AI, hãy kèm theo:
Mục tiêu của query và dashboard sử dụng nó.
Grain kỳ vọng: một dòng đầu ra đại diện cho giao dịch, khách hàng, ngày hay đối tượng nào.
Bảng nào là fact, bảng nào là dimension.
Khóa JOIN và lực lượng kỳ vọng: một-một, nhiều-một hay nhiều-nhiều.
Ý nghĩa của NULL tại các cột quan trọng.
Quy ước khoảng ngày do nghiệp vụ quyết định.
Không cần gửi dữ liệu khách hàng, email, số điện thoại hoặc mã định danh thật vào công cụ AI công khai. Schema đã lược bỏ thông tin nhạy cảm, tên cột tổng quát và vài dòng mẫu đã che dữ liệu thường đủ để review logic.
2. Dùng prompt buộc AI phân biệt quan sát và giả định
text
Bạn là SQL reviewer cho một PR báo cáo.
Bối cảnh nghiệp vụ:
<mục tiêu dashboard hoặc báo cáo>
Grain mong muốn:
<một dòng đại diện cho gì>
Schema và khóa:
<bảng, cột, khóa chính, khóa ngoại, cột có thể NULL>
Quy tắc ngày:
<cột ngày cần dùng, ý nghĩa cận đầu/cuối, múi giờ nếu có>
SQL trong PR:
<dán SQL hoặc diff>
Hãy review theo các mục:
Liệt kê từng JOIN, bảng trái/phải và điều kiện nối
(ON, USING hoặc NATURAL nếu có).
Với mỗi JOIN, nêu nguy cơ nhân dòng. Không được tự giả định
khóa là duy nhất.
Nêu dòng nào có thể mất với INNER JOIN hoặc có cột NULL
với LEFT JOIN.
Kiểm tra điều kiện ngày: cột được lọc, cận đầu/cuối,
dữ liệu có thời gian và múi giờ.
Chỉ ra tên cột hoặc bảng chưa có trong schema được cung cấp.
Đề xuất bộ test dữ liệu nhỏ để xác minh từng rủi ro.
Kết luận theo ba mức: có thể merge, cần chứng minh thêm,
hoặc cần sửa.
Trả lời dưới dạng checklist. Phân biệt rõ:
Quan sát từ SQL
Giả định cần tác giả PR xác nhận
Câu quan trọng nhất là: “Không được tự giả định khóa là duy nhất.” Nó giúp ngăn một phỏng đoán trở thành lời phê duyệt.
3. Yêu cầu test contract trước khi yêu cầu bản sửa
Đừng chỉ hỏi: “SQL này đúng không?”. Hãy yêu cầu AI biến các rủi ro thành điều kiện có thể kiểm tra:
text
Từ SQL và grain đã cung cấp, hãy viết test contract bằng ngôn ngữ tự nhiên:
Dòng nào bắt buộc còn lại?
Dòng nào có thể bị loại?
Cột nào có thể là NULL khi không có bản ghi khớp?
Tình huống nào làm một dòng fact xuất hiện nhiều lần?
Các ca biên cần test cho điều kiện ngày là gì?
Không viết SQL dùng tên bảng hoặc cột không có trong schema.
Nếu thiếu thông tin, hãy ghi rõ câu hỏi cần hỏi tác giả PR.
Đầu ra tốt không phải là câu “an toàn để merge”. Đầu ra tốt phải nêu được điều chưa thể kết luận, chẳng hạn: “Chưa thể xác định JOIN có phải nhiều-một hay không vì chưa có ràng buộc duy nhất ở bảng phải.”
Walkthrough: kiểm tra JOIN và NULL bằng ví dụ PostgreSQL
Tài liệu PostgreSQL minh họa JOIN bằng hai bảng weather và cities.
Với INNER JOIN, chỉ các dòng có thành phố khớp mới được trả về:
sql
SELECT weather.city, weather.templo, weather.temphi,
weather.prcp, weather.date, cities.location
FROM weather
JOIN cities ON weather.city = cities.name;
Trong ví dụ tài liệu, các dòng của San Francisco xuất hiện, còn Hayward không xuất hiện vì không có bản ghi thành phố khớp.
Câu hỏi review cần đặt ra là: bản ghi không khớp có được phép biến mất không?
Nếu yêu cầu là giữ toàn bộ dòng từ weather, dùng LEFT OUTER JOIN:
sql
SELECT
FROM weather
LEFT OUTER JOIN cities ON weather.city = cities.name;
Khi đó, dòng Hayward vẫn xuất hiện; các cột thuộc cities là NULL.
| Ca kiểm tra | Điều cần quan sát |
|---|---|
| Không có dòng dimension khớp | INNER JOIN loại dòng từ bảng trái |
| Không có dòng dimension khớp | LEFT JOIN giữ dòng từ bảng trái; cột bên phải là NULL |
| Có nhiều dòng cùng khớp điều kiện JOIN | Một dòng ở bảng trái có thể tạo nhiều dòng kết quả |
| Schema thay đổi | NATURAL JOIN có thể thay đổi điều kiện nối ngoài ý muốn |
PostgreSQL lưu ý NATURAL JOIN rủi ro hơn vì nó dùng mọi tên cột chung của hai đầu vào làm điều kiện nối. Nếu schema thay đổi và xuất hiện thêm cột trùng tên, kết quả JOIN cũng có thể đổi.
Với SQL cho dashboard, ưu tiên JOIN ... ON ... khi cần thể hiện rõ điều kiện nối. Tài liệu PostgreSQL cũng xem việc qualify cột trong query JOIN là phong cách tốt, vì query ít dễ hỏng hơn nếu sau này có cột trùng tên được thêm vào bảng.
Bộ test nhỏ trước khi merge
Với mọi PR chạm vào JOIN hoặc điều kiện ngày, hãy chạy fixture hoặc CTE nội bộ cho các ca tối thiểu sau:
Một dòng khớp một dòng: kiểm tra cột đầu ra và metric không thay đổi bất ngờ.
Một dòng không khớp: đối chiếu hành vi giữa INNER JOIN và LEFT JOIN.
Một dòng khớp nhiều dòng: kiểm tra nguy cơ nhân bản dòng fact trước khi tổng hợp.
Dòng có khóa thiếu hoặc không khớp: xác nhận hành vi phù hợp với yêu cầu báo cáo.
Ranh giới ngày: thử dữ liệu ở ngày đầu, ngày cuối và thời điểm trong ngày nếu cột có phần thời gian.
Sau vòng AI review, vẫn cần xác minh bằng SQL thực thi và dashboard preview. Hãy so sánh:
Số dòng.
Tổng các metric quan trọng.
Danh sách khóa nghiệp vụ thay đổi.
Các dòng không match hoặc có NULL mới xuất hiện.
AI giúp phát hiện điểm đáng ngờ. Database mới là nơi xác nhận kết quả.
Checklist trước nút merge
[ ] Grain đầu ra được ghi rõ trong PR.
[ ] Mỗi JOIN có điều kiện nối dễ đọc.
[ ] Cột trong query JOIN được qualify khi cần tránh mơ hồ.
[ ] Không có giả định về khóa duy nhất mà chưa được kiểm tra.
[ ] Hành vi NULL sau outer join phù hợp với dashboard.
[ ] Điều kiện ngày có quy ước cận đầu và cận cuối rõ ràng.
[ ] AI không tự thêm bảng, cột hoặc ràng buộc ngoài schema đã cung cấp.
[ ] Fixture đã có ca khớp, không khớp, nhiều khớp và ranh giới ngày.
AI không thay người chịu trách nhiệm về số liệu. Nhưng khi được giao đúng vai trò — hỏi khó, liệt kê giả định và ép PR có test — nó có thể giúp chặn lỗi JOIN, NULL và lọc ngày trước khi chúng trở thành một con số trông có vẻ đúng trên dashboard.