Quay lại yêu cầu đầu bài của tác giả. Khi tôi đọc yêu cầu, tôi không nắm được ý tác giả muồn gì... hic! Quả là năng lực đọc có hạn.
Tuy nhiên, nếu tạm cắt nghĩa ý kiến "hỏi - đáp" thì có thể thấy đầu bài không hẳn là khó và ta hoàn toàn có thể giải quyết mà không cần sử dụng Cross-tab. Phải nói thật - mặc dù Crosstab là rất tiện lợi nhưng ta không nên sử dụng nó mọi nơi - mọi lúc nếu không bắt buộc phải làm vậy. Nếu có cách khác thì ta nên tránh và thay bằng cách khác đó. Và tôi dùng một cách khác như trong bài này.
Mã PHP:
SELECT t00_LopHoc.*, c.Doan, c.Dang
FROM t00_LopHoc INNER JOIN (SELECT b.Malop, Sum(Abs(b.[DoanVien])) AS Doan, Sum(Abs(b.[DangVien])) AS Dang
FROM t01_TrichNgangHS AS b
GROUP BY b.Malop
) AS c ON t00_LopHoc.MaLop = c.Malop;
Ở đây, tác giả chỉ cần đếm số đảng viên trong 1 lớp và đoàn viên trong 1 lớp vì thế ta dùng 1 query dạng nhóm và thực hiện phép đếm.
Trong bài trả lời tôi không dùng phép đếm mà dùng một cách đơn giản hơn đó là tính tổng của tất cả các bản ghi có trường đảng viên = -1 và đổi kết quả sang dạng trị tuyệt đối. Tại sao? Vì nếu đảng viên là đúng, nó sẽ có giá trị là true. Cách này sẽ ổn hơn việc dùng cách đếm (chỉ dùng cách đếm khi ta có dữ liệu không đồng nhất).
Quay lại yêu cầu và giải thích tại sao Cross-tab là nên tránh: Cách thực hiện querry crosstab đòi hỏi tốn nhiều bộ nhớ và tài nguyên máy tính. Đại loại là máy tính sẽ phải đi qua nhiều dòng, mỗi khi thấy dòng có số liệu mới, nó thêm 1 cột và thêm cho đến khi hết bản ghi. Máy tính sẽ dự phòng một khoảng bộ nhớ cho việc đó và nó luôn luôn thường trực 2 động tác, 1 là thực hiện phép toán, 2 là bổ sung cột mới nếu cần. Nếu số bản ghi khác nhau quá lớn, nó sẽ gây lỗi vì phải thêm số trường quá lớn. Để hạn chế số lượng cột đầu ra, người ta có thể bắt máy chỉ hiển thị những trường trong danh mục cho trước bằng cách lấy tên trường sau từ khóa IN (Danh sách).
Chính vì lý do đó, với bài toán, chỉ đòi hỏi thực hiện phép toán với 2 trạng thái - có, không? Thì đơn giản là quay về những Querry truyền thống.
Tiếp theo, với các thống kê khác, bạn hoàn toàn có thể áp dụng cách tiếp cận tôi đã mô tả bằng cách làm các query thống kê riêng, chẳng hạn:
1. Thống kê Nam, Nữ
2. Thống kê Dân tộc (cái này thì nên dùng Crosstab vì ta không biết trước số dân tộc của một lớp - nếu bạn muốn phân theo dân tộc gì? Dao, Kinh ...., nếu chỉ muốn đếm thì áp dụng như cách tôi dùng). Ngoài ra, nếu bạn muốn khống chế số nhóm dân tộc trong querry- Crosstab thì bạn có thể dùng cách như sau:
Mã PHP:
TRANSFORM Count(a.MaHS) AS CountOfMaHS
SELECT a.Malop, Count(a.MaHS) AS [Total Of MaHS]
FROM t01_TrichNgangHS AS a
GROUP BY a.Malop
PIVOT a.DanToc In ("Sơ Drá","Kinh","H'Mông");
Trong ví dụ này, nếu H'Mông không có bản ghi nào thì số liệu sẽ là 0...
3. Thống kê đảng, đoàn
Tất cả các querry trên đều đảm bảo phải có trường Mã lớp.... sau đó dùng Querry thống kê chung là xong.
Tôi xin có sự chia sẻ nhỏ nhặt vậy, nếu cần nói nhiều hơn về Cross-tab - tôi sẽ cố gắng võ vẽ thêm nếu bạn cần...
Thân