Format câu lệnh SQL cho dễ đọc: công cụ làm gì, làm hỏng gì và quy ước trình bày nên theo
Công cụ viết hoa các từ khóa SQL, ngắt dòng trước những mệnh đề chính và tách danh sách cột theo dấu phẩy, biến một truy vấn viết liền thành dạng đọc được theo tầng. Kèm một nút nén ngược lại về một dòng. Truy vấn bạn dán vào được xử lý ngay trên trình duyệt và không gửi đi đâu.
Tính năng nổi bật
- Viết hoa hơn năm mươi từ khóa SQL thông dụng, không phân biệt bạn gõ hoa hay thường
- Ngắt dòng trước các mệnh đề chính gồm SELECT, FROM, WHERE, JOIN, GROUP BY, ORDER BY, HAVING, LIMIT và UNION
- Ngắt dòng trước các toán tử nối điều kiện AND và OR để mỗi điều kiện nằm một dòng
- Tách danh sách sau dấu phẩy thành từng dòng có thụt lề hai dấu cách
- Nút nén ngược gộp toàn bộ truy vấn về một dòng
- Hai ô đặt song song để đối chiếu truy vấn gốc với kết quả
- Nút sao chép kết quả và nút xóa nhanh ô nhập
- Chạy hoàn toàn trên trình duyệt, truy vấn không được gửi lên máy chủ
Vì sao truy vấn viết liền một dòng lại tốn thời gian đến vậy
Truy vấn SQL trong thực tế thường không được viết ra mà được sinh ra hoặc chép lại: lấy từ nhật ký truy vấn chậm của cơ sở dữ liệu, chép từ mã nguồn nơi câu lệnh nằm trong một chuỗi ghép nhiều đoạn, lấy từ công cụ báo cáo, hoặc nhận từ đồng nghiệp qua tin nhắn. Ở dạng đó, một truy vấn có ba phép nối bảng và năm điều kiện lọc trở thành một dòng dài vài trăm ký tự mà mắt không thể tách ra được đâu là mệnh đề nào. Khi cần trả lời những câu hỏi rất cơ bản như truy vấn này nối những bảng nào, điều kiện lọc nằm ở đâu, có nhóm theo cột nào không, bạn phải đọc đi đọc lại nhiều lần. Việc ngắt dòng theo mệnh đề giải quyết đúng chuyện này: sau khi định dạng, cấu trúc truy vấn hiện ra thành từng tầng và bạn nắm được nó trong vài giây. Đây là bước đầu tiên nên làm trước khi tối ưu hay sửa bất kỳ truy vấn nào bạn không tự viết.
Lợi ích khi sử dụng
- Nắm được cấu trúc một truy vấn lạ trong vài giây thay vì dò từng đoạn
- Mỗi điều kiện lọc nằm một dòng nên dễ soi điều kiện nào thừa hoặc thiếu
- Từ khóa viết hoa đồng nhất giúp mắt phân biệt ngay từ khóa với tên bảng và tên cột
- Truy vấn chứa tên bảng và tên cột nội bộ không rời khỏi trình duyệt
- Có sẵn cả hai chiều định dạng và nén trong cùng một màn hình
Cách định dạng một câu lệnh SQL
- 1Dán truy vấn vào ô bên trái, có thể dán cả truy vấn nhiều dòng hoặc truy vấn viết liền.
- 2Bấm nút định dạng, kết quả hiện ngay ở ô bên phải với từ khóa viết hoa và các mệnh đề tách dòng.
- 3Đọc từ trên xuống theo từng mệnh đề để nắm cấu trúc: lấy dữ liệu từ đâu, nối với bảng nào, lọc theo điều kiện gì.
- 4Kiểm tra lại hai chỗ dễ sai là chuỗi ký tự có chứa dấu phẩy và các dòng chú thích, vì đây là nơi công cụ có thể làm sai nội dung.
- 5Bấm sao chép để lấy kết quả, hoặc bấm nút nén nếu bạn cần bản gộp về một dòng để đưa vào một chuỗi trong mã nguồn.
Công cụ xử lý truy vấn theo ba bước
Bước thứ nhất là chuẩn hóa chữ hoa: công cụ quét qua danh sách hơn năm mươi từ khóa và chuyển mọi lần xuất hiện của chúng thành chữ hoa, bất kể bạn gõ thế nào. Danh sách gồm các mệnh đề chính, các kiểu nối bảng, các toán tử logic và cả các hàm tổng hợp như đếm, tổng, trung bình, lớn nhất và nhỏ nhất. Bước thứ hai là ngắt dòng: công cụ chèn một dấu xuống dòng ngay trước mỗi mệnh đề trong nhóm được coi là điểm ngắt, gồm SELECT, FROM, WHERE, AND, OR, JOIN, ORDER BY, GROUP BY, HAVING, LIMIT và UNION. Nhờ bước này mà mỗi điều kiện nối bằng AND hay OR đều nằm trên dòng riêng, rất tiện khi soi logic lọc. Bước thứ ba là tách danh sách: mọi dấu phẩy trong truy vấn được thay bằng dấu phẩy kèm xuống dòng và hai dấu cách thụt lề, nên danh sách cột trong mệnh đề SELECT trở thành mỗi cột một dòng. Kết quả cuối cùng được cắt bỏ dòng trống thừa ở đầu. Cả ba bước đều làm bằng phép thay thế theo mẫu chứ không qua bộ phân tích cú pháp SQL, và đó chính là nguồn gốc của những hạn chế nói ở phần sau.
Ba tình huống công cụ làm sai nội dung truy vấn
Tình huống thứ nhất và nguy hiểm nhất là chuỗi ký tự có chứa dấu phẩy. Vì bước tách danh sách thay mọi dấu phẩy trong toàn bộ văn bản, một điều kiện so sánh với chuỗi chứa dấu phẩy sẽ bị chèn dấu xuống dòng vào giữa chuỗi, và giá trị đem so sánh không còn giống giá trị ban đầu nữa. Truy vấn vẫn chạy được nhưng trả về sai kết quả, đây là kiểu lỗi khó phát hiện nhất. Tình huống thứ hai là chú thích. Một dòng chú thích bắt đầu bằng hai dấu gạch nối vốn có hiệu lực tới hết dòng; khi công cụ chèn thêm dấu xuống dòng vào giữa dòng chú thích đó, phần chữ phía sau bị đẩy sang dòng mới và trở thành mã có hiệu lực, khiến truy vấn thực thi cả những đoạn lẽ ra bị bỏ qua. Tình huống thứ ba nhẹ hơn nhưng gây khó chịu: các kiểu nối bảng ghép hai từ như nối trái hay nối trong sẽ bị tách ra, chữ chỉ hướng nằm cuối dòng trên còn chữ nối nằm đầu dòng dưới. Kết quả vẫn đúng về mặt thực thi nhưng nhìn rất khó chịu, và bạn nên gộp lại bằng tay.
Quy ước trình bày SQL mà một nhóm nên thống nhất
Ngoài phần công cụ làm tự động, có vài quy ước đáng thống nhất trong nhóm để mọi truy vấn đọc giống nhau. Thứ nhất là chữ hoa cho từ khóa: đây là quy ước lâu đời và vẫn hữu ích vì nó giúp mắt tách ngay từ khóa khỏi tên bảng và tên cột, nhất là khi cơ sở dữ liệu của bạn đặt tên cột bằng chữ thường. Thứ hai là vị trí dấu phẩy trong danh sách cột: đặt cuối dòng là cách quen thuộc, còn đặt đầu dòng thì xấu hơn một chút nhưng có lợi thật là khi thêm hoặc bớt cột, dòng thay đổi trong bản so sánh mã nguồn chỉ có một chứ không phải hai. Thứ ba là bí danh: luôn đặt bí danh ngắn và có nghĩa cho bảng khi truy vấn có nhiều bảng, và luôn viết rõ tên bảng trước tên cột trong mệnh đề nối và mệnh đề lọc, vì thiếu điều này thì người đọc phải đoán cột thuộc bảng nào. Thứ tư là độ dài dòng: giữ dưới khoảng một trăm ký tự để đọc được trong khung so sánh mã nguồn hai cột. Thứ năm là luôn ghi rõ danh sách cột thay vì dùng dấu sao, kể cả khi bạn cần tất cả các cột.
Thứ tự viết khác thứ tự thực thi, và điều đó giải thích nhiều lỗi
Một truy vấn được viết theo thứ tự SELECT trước rồi FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT. Nhưng cơ sở dữ liệu lại thực thi theo thứ tự khác: trước tiên là FROM cùng các phép nối bảng, rồi WHERE lọc từng dòng, rồi GROUP BY gom nhóm, rồi HAVING lọc trên các nhóm, sau đó mới tới SELECT chọn cột và tính biểu thức, rồi DISTINCT bỏ trùng, rồi ORDER BY sắp xếp và cuối cùng LIMIT cắt lấy phần đầu. Hiểu thứ tự này giải thích được ngay ba lỗi rất hay gặp. Lỗi thứ nhất: bí danh bạn đặt trong mệnh đề SELECT không dùng được trong WHERE, vì lúc WHERE chạy thì SELECT chưa được xử lý; nhưng dùng được trong ORDER BY vì mệnh đề đó chạy sau. Lỗi thứ hai: đưa điều kiện lọc trên hàm tổng hợp vào WHERE sẽ báo lỗi, phải đưa vào HAVING, vì WHERE chạy trước khi nhóm được hình thành. Lỗi thứ ba: đặt điều kiện của bảng bên phải trong phép nối trái vào mệnh đề WHERE sẽ vô hiệu hóa tính chất nối trái và biến nó thành nối trong; muốn giữ đúng thì điều kiện đó phải nằm trong mệnh đề ON.
Định dạng đẹp không làm truy vấn chạy nhanh hơn
Cần nói rõ để không kỳ vọng sai: khoảng trắng và cách xuống dòng không ảnh hưởng gì tới tốc độ, bộ tối ưu truy vấn của cơ sở dữ liệu nhìn cây cú pháp chứ không nhìn cách trình bày. Nếu mục tiêu của bạn là truy vấn chạy nhanh hơn, việc cần làm nằm ở chỗ khác. Bước đầu tiên luôn là xem kế hoạch thực thi bằng lệnh phân tích của hệ quản trị bạn đang dùng, để biết cơ sở dữ liệu thực sự quét toàn bộ bảng hay dùng chỉ mục. Từ đó có vài nguyên tắc thường đúng: đặt chỉ mục cho các cột xuất hiện trong mệnh đề lọc và mệnh đề nối, ưu tiên các cột có độ phân biệt cao; tránh bọc hàm quanh cột trong mệnh đề lọc vì làm vậy khiến chỉ mục trên cột đó không dùng được, ví dụ lọc theo năm bằng cách gọi hàm trích năm từ cột ngày sẽ chậm hơn hẳn so với lọc theo khoảng ngày; tránh mẫu tìm kiếm bắt đầu bằng ký tự đại diện vì chỉ mục không dùng được cho phần đầu chuỗi; và chỉ lấy đúng những cột cần dùng, đặc biệt khi bảng có cột kiểu văn bản dài. Định dạng lại truy vấn chỉ là bước chuẩn bị để bạn nhìn ra những chỗ này.
Câu hỏi thường gặp (FAQ)
Truy vấn tôi dán vào có bị gửi lên máy chủ không?
Không. Việc viết hoa từ khóa, ngắt dòng và tách danh sách đều chạy bằng JavaScript ngay trong tab trình duyệt, không có lời gọi mạng nào mang nội dung đi. Đóng tab là truy vấn biến mất, nên bạn dùng được với câu lệnh chứa tên bảng và tên cột nội bộ.
Vì sao chuỗi ký tự trong truy vấn bị xuống dòng ở giữa?
Vì bước tách danh sách thay mọi dấu phẩy trong toàn bộ văn bản, kể cả dấu phẩy nằm trong chuỗi. Giá trị đem so sánh do đó không còn giống ban đầu và truy vấn có thể trả về sai kết quả. Hãy kiểm tra lại mọi chuỗi có dấu phẩy sau khi định dạng.
Chú thích trong truy vấn có bị ảnh hưởng không?
Có, và đây là chỗ nguy hiểm. Chú thích bắt đầu bằng hai dấu gạch nối chỉ có hiệu lực tới hết dòng, nên khi công cụ chèn thêm dấu xuống dòng vào giữa, phần chữ phía sau bị đẩy sang dòng mới và trở thành mã có hiệu lực. Hãy xóa chú thích trước khi định dạng.
Vì sao phép nối trái bị tách thành hai dòng?
Vì công cụ xử lý từ khóa nối bảng trước khi xử lý cụm nối trái, nên dấu xuống dòng đã được chèn vào giữa hai từ. Truy vấn vẫn chạy đúng vì SQL không quan tâm chỗ xuống dòng, nhưng nhìn khó chịu và bạn nên gộp hai dòng đó lại bằng tay.
Công cụ có thụt lề cho truy vấn con không?
Không. Nó không theo dõi độ sâu của dấu ngoặc nên mọi mệnh đề đều nằm ở cùng một mức, kể cả mệnh đề nằm trong truy vấn con. Với truy vấn có nhiều tầng lồng nhau, bạn nên thụt lề tay hoặc dùng công cụ định dạng tích hợp trong phần mềm quản trị cơ sở dữ liệu.
Có hỗ trợ riêng cho từng hệ quản trị cơ sở dữ liệu không?
Không, công cụ dùng chung một danh sách từ khóa cho mọi hệ. Phần cú pháp chung thì xử lý tốt, còn các từ khóa riêng của từng hệ như cú pháp phân trang khác nhau hay các hàm đặc thù sẽ không được viết hoa và không tạo điểm ngắt dòng.
Định dạng lại có làm truy vấn chạy nhanh hơn không?
Không. Khoảng trắng và cách xuống dòng không ảnh hưởng gì tới tốc độ vì bộ tối ưu nhìn cây cú pháp chứ không nhìn cách trình bày. Muốn nhanh hơn, hãy xem kế hoạch thực thi rồi xử lý chỉ mục và điều kiện lọc.
Vì sao bí danh đặt trong SELECT lại không dùng được trong WHERE?
Vì thứ tự thực thi khác thứ tự viết: mệnh đề WHERE chạy trước mệnh đề SELECT nên lúc đó bí danh chưa tồn tại. Cùng bí danh đó lại dùng được trong ORDER BY vì mệnh đề sắp xếp chạy sau SELECT. Muốn lọc theo biểu thức, hãy viết lại cả biểu thức trong WHERE.
Khi nào dùng WHERE và khi nào dùng HAVING?
WHERE lọc trên từng dòng dữ liệu và chạy trước khi gom nhóm, còn HAVING lọc trên kết quả đã gom nhóm nên dùng được với các hàm tổng hợp như đếm hay tổng. Đặt điều kiện lọc thông thường vào WHERE sẽ nhanh hơn vì nó giảm số dòng trước khi gom nhóm.
Nên viết hoa từ khóa SQL hay không?
Về mặt thực thi thì không quan trọng vì SQL không phân biệt chữ hoa chữ thường ở từ khóa. Về mặt đọc thì có ích thật, nhất là khi cơ sở dữ liệu đặt tên bảng và cột bằng chữ thường, vì mắt tách được ngay đâu là từ khóa đâu là tên do bạn đặt.
Nút nén dùng để làm gì?
Để gộp truy vấn về một dòng, tiện khi bạn cần đưa câu lệnh vào một chuỗi trong mã nguồn hoặc vào một ô cấu hình chỉ nhận một dòng. Lưu ý là nếu truy vấn có chú thích bắt đầu bằng hai dấu gạch nối, việc gộp một dòng sẽ khiến toàn bộ phần sau bị vô hiệu hóa.
Có kiểm tra được truy vấn viết đúng cú pháp hay không?
Không. Công cụ chỉ trình bày lại chứ không phân tích cú pháp, nên một truy vấn sai vẫn được định dạng bình thường. Muốn kiểm tra cú pháp, hãy chạy thử trong phần mềm quản trị cơ sở dữ liệu, tốt nhất là trên bản sao dữ liệu thử nghiệm chứ không phải dữ liệu thật.
Từ khóa liên quan
- format sql online
- làm đẹp câu lệnh sql
- sql formatter online miễn phí
- beautify sql query
- định dạng truy vấn sql
- viết hoa từ khóa sql
- thứ tự thực thi mệnh đề sql
- where và having khác nhau
- left join và inner join
- tối ưu truy vấn sql
- đọc kế hoạch thực thi truy vấn
- chỉ mục trong cơ sở dữ liệu
- quy ước viết sql cho nhóm
- nén câu lệnh sql thành một dòng
- sql khó đọc từ log
- bí danh bảng trong sql
- truy vấn con trong sql
- công cụ sql cho lập trình viên
- format sql không cần cài đặt
- sql chạy chậm phải làm gì
