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 LAG: dòng trước không nhất thiết là ngày hôm trước

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

Bạn có bảng lượt xử lý theo ngày và muốn hiển thị chênh lệch trên trang vận hành. Một thiết bị có dữ liệu thứ Hai và thứ Tư, nhưng thiếu thứ Ba. Nếu dùng LAG rồi đặt nhãn là “so với hôm qua”, người xem có thể đọc nhầm một thay đổi qua hai ngày thành thay đổi trong một ngày.

Xác định thứ tự của phép so sánh

LAG lấy giá trị từ dòng đứng trước theo thứ tự trong cửa sổ. PARTITION BY giúp mỗi thiết bị có dòng trước riêng. ORDER BY bên trong OVER xác định thứ tự cho phép tính, còn ORDER BY cuối SELECT phục vụ việc trình bày kết quả. Hai việc này cần được viết riêng nếu muốn cả kết quả tính và thứ tự hiển thị rõ ràng.

Bài dùng SQLite 3.54.0 và dữ liệu giả lập. Giả định mỗi thiết bị có tối đa một dòng mỗi ngày, ngày ở dạng ISO cố định. Nếu bảng thật có nhiều dòng trong ngày, hãy tổng hợp về đúng cấp hoặc thêm một khóa phân xử thứ tự trước khi chọn ý nghĩa của dòng trước.

Tính cả ngày và giá trị trước đó

WITH readings(device, day, amount) AS (
  VALUES ('A', '2026-11-01', 10),
         ('A', '2026-11-03', 16),
         ('A', '2026-11-04', 19),
         ('B', '2026-11-03', 30)
), ordered AS (
  SELECT device, day, amount,
         LAG(day) OVER w AS previous_day,
         LAG(amount) OVER w AS previous_amount
  FROM readings
  WINDOW w AS (PARTITION BY device ORDER BY day)
)
SELECT device, day, previous_day,
       amount - previous_amount AS delta_from_previous,
       CASE WHEN previous_day = date(day, '-1 day')
            THEN amount - previous_amount END AS daily_delta
FROM ordered
ORDER BY device, day;

Thiết bị A ngày 03 có dòng trước là ngày 01, nên chênh lệch so lần ghi trước bằng 6. Cột daily_delta là NULL vì không có dòng của ngày 02 đứng ngay trước. Ngày 04 có đủ hai ngày liên tiếp nên cả hai cột đều bằng 3. Thiết bị B chỉ có một dòng, không mượn số liệu của A để tính.

Chọn cách xử lý ngày thiếu

Nếu người xem thực sự muốn biết thay đổi so với lần ghi gần nhất, hãy đặt tên cột theo ý đó và hiển thị cả ngày của lần ghi trước. Nếu muốn chênh lệch theo lịch, có thể để trống khi thiếu dữ liệu, như CASE ở trên. Một lựa chọn khác là tạo lịch đầy đủ rồi nối số liệu vào; lúc đó cần quyết định ngày thiếu là chưa có dữ liệu hay có số lượng thực bằng 0.

Không biến NULL thành 0 chỉ để biểu đồ liền mạch. Một ngày không nhận được bản ghi có thể cần điều tra đường truyền, trong khi số 0 hợp lệ thể hiện một hoạt động đã được đo. Chọn cách thể hiện hai trạng thái trước khi tổng hợp lên dashboard.

Kiểm tra và giới hạn

Đọc kết quả theo từng thiết bị, kiểm tra dòng đầu và một cặp ngày liên tiếp. Thêm trường hợp ngày trống ở giữa. Nếu muốn chỉ hiển thị một khoảng ngắn, hãy cân nhắc tính LAG trước khi lọc khoảng hiển thị: lọc quá sớm có thể bỏ mất dòng dùng làm mốc cho ngày đầu của báo cáo.

Fixture chỉ chạy truy vấn đọc trong SQLite, không đo hiệu năng hoặc kiểm tra dữ liệu theo múi giờ. Với hệ khác, kiểm tra cú pháp trừ ngày và chính sách chuyển timestamp thành ngày trước khi chuyển truy vấn. Đừng dựa vào thứ tự chèn dữ liệu để suy ra dòng trước.

Kết luận

LAG giúp so với dòng trước trong một thứ tự đã khai báo. Hãy mang theo ngày của dòng đó để phân biệt “lần ghi trước” với “hôm qua” và giữ ý nghĩa của dữ liệu thiếu.

Nguồn tham khảo

  • SQLite: Window functions

Tags: SQLSQLiteWindow functions
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 DISTINCT và NULL: đếm giá trị khác nhau hay đếm cả nhóm thiếu?

by Suong Nguyen
11/11/2026
0

Dùng fixture SQL nhỏ để phân biệt số dòng, số giá trị khác NULL, giá trị duy nhất và nhóm NULL trong báo cáo.

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

SQL COALESCE: chuỗi rỗng chưa phải NULL, xử lý bằng NULLIF và TRIM

by Suong Nguyen
10/11/2026
0

Phân biệt NULL, chuỗi rỗng và chuỗi chỉ có dấu cách trước khi chọn giá trị dự phòng cho một trường văn bản.

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

by Suong Nguyen
09/11/2026
0

Kiểm tra phép chia số nguyên, lỗi CAST quá muộn và mẫu số bằng 0 bằng các truy vấn SQLite nhỏ, kèm đối chiếu PostgreSQL 17.

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.

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

findLast hay vòng lặp ngược: tìm bản ghi cuối mà không đảo mảng

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 Keyboard.dismiss: đóng bàn phím mà vẫn giữ bản nháp
  • Map.get trả undefined: khóa không tồn tại hay đã lưu giá trị undefined?
  • Handler.removeCallbacks: giữ đúng Runnable để hủy tác vụ chờ

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