aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
SAVED POSTS
aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
aedev.net
No Result
View All Result
Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

SQL tính tỷ lệ: ép kiểu trước phép chia để không mất phần thập phân

Suong Nguyen by Suong Nguyen
09/11/2026
in Backend
0
585
SHARES
3.2k
VIEWS
Summarize with ChatGPTShare to Facebook

Bạn có một đơn đã thanh toán trên tổng bốn đơn, nhưng API trả tỷ lệ bằng 0. Việc làm tròn ở giao diện chưa chắc là nguyên nhân. Nếu phép chia được thực hiện giữa hai số nguyên, phần thập phân có thể đã bị loại ngay trong database. Ép kết quả ấy sang kiểu số thực sau đó không lấy lại thông tin đã mất.

Bài cập nhật ngày 09/11/2026, chạy các truy vấn trên SQLite 3.54.0 và đối chiếu tài liệu PostgreSQL 17. Chưa chạy PostgreSQL server, ORM hoặc benchmark. Ví dụ nhận sẵn số lượng, tập trung vào phép chia; nó không xây dựng truy vấn đếm đơn theo trạng thái.

Nhìn kiểu ở ngay phép toán đầu tiên

Chạy truy vấn này trong SQLite:

SELECT
  1 / 4 AS integer_ratio,
  CAST(1 / 4 AS REAL) AS cast_too_late,
  CAST(1 AS REAL) / 4 AS cast_before_division,
  1.0 / 4 AS real_ratio;

Kết quả lần lượt là 0, 0.0, 0.25, 0.25. SQLite expressions mô tả phép toán dùng số nguyên khi hai toán hạng là số nguyên và không tràn. Vì vậy, CAST của biểu thức 1 / 4 chỉ nhận được số 0 đã tính xong.

Đặt CAST ở tử số làm phép chia nhận một toán hạng REAL ngay từ đầu. Hằng số 1.0 cũng tạo khác biệt về kiểu so với 1. Khi đọc query có nhiều tầng expression, hãy xác định phép toán nào xảy ra trước thay vì chỉ nhìn kiểu của cột kết quả cuối.

Xử lý rõ trường hợp chưa có mẫu số

Tỷ lệ không xác định khi tổng số mẫu bằng 0. Ví dụ dưới chọn trả NULL cho tình huống đó:

WITH counts(paid, total) AS (
  VALUES (1, 4), (0, 4), (0, 0)
)
SELECT
  paid,
  total,
  CAST(paid AS REAL) / NULLIF(total, 0) AS paid_ratio
FROM counts
ORDER BY total DESC, paid DESC;

Ba tỷ lệ theo thứ tự là 0.25, 0.0, NULL. NULLIF của SQLite trả NULL khi hai đối số bằng nhau, nên mẫu số 0 được chuyển thành NULL trước phép chia. Dòng có tổng 4 và paid 0 vẫn có tỷ lệ bằng 0; nó khác dòng chưa có đơn nào để tính.

Nếu API trả JSON, hãy giữ quyết định này nhất quán trong hợp đồng: NULL có thể mang nghĩa “chưa đủ dữ liệu”. Việc đổi nó thành 0 để vẽ biểu đồ là một lựa chọn sản phẩm cần được nêu rõ, vì người đọc có thể hiểu 0 là đã quan sát nhưng không có đơn paid.

Tỷ lệ và phần trăm là hai thang hiển thị

SELECT
  CAST(1 AS REAL) / NULLIF(4, 0) AS ratio,
  100.0 * 1 / NULLIF(4, 0) AS percent;

Kết quả là 0.25 và 25.0. Chọn một thang để lưu hoặc truyền qua API và ghi rõ tên trường. Nếu backend đã nhân 100 mà frontend tiếp tục nhân nữa, phần trăm sẽ sai dù phép chia có kiểu đúng. Không suy ra thang đo chỉ từ việc cột chứa số thực.

Tránh viết (paid / total) * 100.0 khi paid và total vẫn là số nguyên, vì lỗi có thể xuất hiện trước phép nhân. Cũng đừng chỉ kiểm tra trường hợp hai số chia hết: 4 / 4 có thể che mất lỗi mà 1 / 4 sẽ phát hiện.

Đối chiếu khi dự án dùng PostgreSQL

PostgreSQL 17 mathematical operators cũng phân biệt phép chia số nguyên và số có phần thập phân. Nếu cần số học decimal trong PostgreSQL, hãy đọc quy tắc kiểu numeric của hệ thống đó và ép kiểu toán hạng phù hợp; không sao chép tên REAL rồi mặc định độ chính xác giống mọi database.

PostgreSQL NULLIF mô tả cùng ý tưởng đổi một giá trị bằng giá trị so sánh thành NULL. Phần đối chiếu này dựa trên tài liệu, không phải kết quả chạy query trên PostgreSQL trong bài.

Kiểm tra miền dữ liệu và giới hạn

Thêm ca một phần tư, không paid trên tổng dương, tổng bằng 0 và paid bằng total. Rà thêm đầu vào NULL và kiểu thực tế của cột hoặc parameter từ driver. Ví dụ giả định hai số đếm là số nguyên không âm và paid không vượt total; phép CAST không tự xác minh các điều kiện nghiệp vụ đó.

SQLite REAL dùng số thực nhị phân, nên đây không phải mẫu thiết kế cho tính tiền cần độ chính xác decimal. Với tỷ lệ báo cáo, kiểm tra đầu ra bằng sai số phù hợp, còn việc làm tròn để hiển thị nên được quyết định riêng. Bước sửa đầu tiên vẫn là ép kiểu ở đúng toán hạng trước khi phép chia diễn ra.

Nguồn tham khảo

  • SQLite: Expressions
  • SQLite: NULLIF
  • PostgreSQL 17: Mathematical operators
  • PostgreSQL 17: NULLIF

Tags: Kiểu dữ liệuSQLSQLite
SummarizeShare234
Suong Nguyen

Suong Nguyen

Related Stories

Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

COUNT với CASE: vì sao ELSE 0 vẫn đếm cả dòng không khớp?

by Suong Nguyen
08/11/2026
0

Dựng dữ liệu nhỏ để phân biệt COUNT(CASE), SUM(CASE) và FILTER, rồi kiểm tra số đếm khi không có bản ghi.

Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

SQL RANK và DENSE_RANK: đồng hạng có làm bỏ số thứ hạng tiếp theo?

by Suong Nguyen
07/11/2026
0

Dùng dữ liệu đồng điểm để chọn RANK, DENSE_RANK hoặc ROW_NUMBER, đồng thời tránh vô tình phá nhóm đồng hạng bằng cột ID.

Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

SQLite REPLACE: cột bị bỏ qua có thể mất giá trị cũ

by Suong Nguyen
06/11/2026
0

So sánh INSERT OR REPLACE với ON CONFLICT DO UPDATE để thấy một cột không truyền vào có được giữ lại hay không.

Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

SQL AND và OR: giữ điều kiện tenant bằng dấu ngoặc đúng chỗ

by Suong Nguyen
05/11/2026
0

Tái hiện lỗi lọc trạng thái làm lọt bản ghi tenant khác và kiểm tra nhóm điều kiện bằng dữ liệu đối chứng.

Next Post
Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

Array.at(-1) và array[-1]: đọc phần tử cuối hay thuộc tính tên âm?

0 0 votes
Article Rating
Subscribe
Login
Notify of
guest
guest
0 Comments
Oldest
Newest Most Voted
AE Dev

AE Dev mang đến các bài viết về lập trình, mobile app, backend, frontend, WordPress và công nghệ, phù hợp cho developer muốn học hỏi và cập nhật kiến thức thực tế.

Recent Posts

  • React Native ScrollView: đặt style cho khung cuộn hay vùng nội dung?
  • Phỏng vấn JavaScript: throw trong async function đi vào catch nào?
  • Android CheckBox: đổi isChecked bằng code vẫn có thể gọi listener

Categories

  • AI
  • Backend
  • Đánh giá
  • DevOps
  • Flutter
  • Hướng dẫn
  • Lập trình Mobile
  • Phỏng vấn
  • React Native
  • Uncategorized

Weekly Newsletter

  • Buy JNews
  • Support Forum
  • Pre-sale Question
  • Contact Us

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • AI
  • Mobile
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
  • Flutter

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

wpDiscuz
0
0
Would love your thoughts, please comment.x
()
x
| Reply