Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 15 kết quả

Đề tài: vấn đề INNER JOIN khi dữ liệu rỗng

  1. #1
    Ngày gia nhập
    05 2010
    Bài viết
    505

    Mặc định vấn đề INNER JOIN khi dữ liệu rỗng

    Hic.

    Mình có vấn đề sau với câu lệnh sql INNER JOIN. câu lệnh như bên dưới và mục đích là lấy ra số nhân viên của từng phòng ban của từng tháng dựa vào 2 trường ngayVaoCty (ngày vào làm) và ngayNghi (ngày nghỉ việc)

    SELECT sq1.phongBan, sq2.soNV AS Thang1, sq3.soNV AS Thang2, sq4.soNV AS Thang3, sq5.soNV AS Thang4, sq6.soNV AS Thang5, sq7.soNV AS Thang6, sq8.soNV AS Thang7, sq9.soNV AS Thang8, sq10.soNV AS Thang9, sq11.soNV AS Thang10, sq12.soNV AS Thang11, sq13.soNV AS Thang12 from tblNhanVien sq1
    INNER JOIN (SELECT phongBan, count(id) as soNV FROM tblNhanVien where ngayVaoCty < '01/02/2011' and ngayNghi >= '01/02/2011' GROUP BY phongBan ) sq2 ON sq1.phongBan = sq2.phongBan
    INNER JOIN (SELECT phongBan, count(id) as soNV FROM tblNhanVien where ngayVaoCty < '01/03/2011' and ngayNghi >= '01/03/2011' GROUP BY phongBan ) sq3 ON sq1.phongBan = sq3.phongBan
    INNER JOIN (SELECT phongBan, count(id) as soNV FROM tblNhanVien where ngayVaoCty < '01/04/2011' and ngayNghi >= '01/04/2011' GROUP BY phongBan ) sq4 ON sq1.phongBan = sq4.phongBan
    INNER JOIN (SELECT phongBan, count(id) as soNV FROM tblNhanVien where ngayVaoCty < '01/05/2011' and ngayNghi >= '01/05/2011' GROUP BY phongBan ) sq5 ON sq1.phongBan = sq5.phongBan
    INNER JOIN (SELECT phongBan, count(id) as soNV FROM tblNhanVien where ngayVaoCty < '01/06/2011' and ngayNghi >= '01/06/2011' GROUP BY phongBan ) sq6 ON sq1.phongBan = sq6.phongBan
    INNER JOIN (SELECT phongBan, count(id) as soNV FROM tblNhanVien where ngayVaoCty < '01/07/2011' and ngayNghi >= '01/07/2011' GROUP BY phongBan ) sq7 ON sq1.phongBan = sq7.phongBan
    INNER JOIN (SELECT phongBan, count(id) as soNV FROM tblNhanVien where ngayVaoCty < '01/08/2011' and ngayNghi >= '01/08/2011' GROUP BY phongBan ) sq8 ON sq1.phongBan = sq8.phongBan
    INNER JOIN (SELECT phongBan, count(id) as soNV FROM tblNhanVien where ngayVaoCty < '01/09/2011' and ngayNghi >= '01/09/2011' GROUP BY phongBan ) sq9 ON sq1.phongBan = sq9.phongBan
    INNER JOIN (SELECT phongBan, count(id) as soNV FROM tblNhanVien where ngayVaoCty < '01/10/2011' and ngayNghi >= '01/10/2011' GROUP BY phongBan ) sq10 ON sq1.phongBan = sq10.phongBan
    INNER JOIN (SELECT phongBan, count(id) as soNV FROM tblNhanVien where ngayVaoCty < '01/11/2011' and ngayNghi >= '01/11/2011' GROUP BY phongBan ) sq11 ON sq1.phongBan = sq11.phongBan
    INNER JOIN (SELECT phongBan, count(id) as soNV FROM tblNhanVien where ngayVaoCty < '01/12/2011' and ngayNghi >= '01/12/2011' GROUP BY phongBan ) sq12 ON sq1.phongBan = sq12.phongBan
    INNER JOIN (SELECT phongBan, count(id) as soNV FROM tblNhanVien where ngayVaoCty < '01/01/2012' and ngayNghi >= '01/01/2012' GROUP BY phongBan ) sq13 ON sq1.phongBan = sq13.phongBan
    group by sq1.phongBan,sq2.soNV,sq3.soNV,sq4.soNV,sq5.soNV,s q6.soNV,sq7.soNV,sq8.soNV,sq9.soNV,sq10.soNV,sq11. soNV,sq12.soNV,sq13.soNV
    kết quả trả về như hình dứoi:


    Mình cũng ko chắc là query trên có ổn và cho kết quả chính xác ko, nhưng có một vấn đề là ví dụ phòng ABC tháng 6 mới bắt đầu có (tháng 6 mới có thêm phòng này) thì làm sao để soNV của nó cho các tháng trc (tháng 5, 4, 3,..) phải là 0 (hiện tại nó = tháng 6).

    Rất mong các bro chỉ giáo.

    Thanks
    Đã được chỉnh sửa lần cuối bởi luxubu : 10-08-2011 lúc 06:09 PM.

  2. #2
    Ngày gia nhập
    06 2011
    Bài viết
    93

    Vậy thì bạn dùng LEFT JOIN đi nếu không có nó vẫn hiện ra mà.

  3. #3
    Ngày gia nhập
    05 2010
    Bài viết
    505

    Mình thử rồi mà vẫn ko đc bạn ạ, ví dụ tháng 6 mới có phòng Kiểm Toán, lẽ ra tháng 1, 2, 3, 4, 5 số nhân viên phải là 0, thì nó lại là 4 (giống tháng 6). Giờ làm sao để nó = 0 nhỉ ?
    Thanks

  4. #4
    Ngày gia nhập
    02 2011
    Bài viết
    34

    Bạn dùng UNION ALL đi, tách ra từng bảng, rồi SUM lại
    Đã được chỉnh sửa lần cuối bởi chuotdongbn123 : 10-08-2011 lúc 08:37 AM.

  5. #5
    Ngày gia nhập
    05 2010
    Bài viết
    505

    Trích dẫn Nguyên bản được gửi bởi chuotdongbn123 Xem bài viết
    Bạn dùng UNION ALL đi, tách ra từng bảng, rồi SUM lại
    hi, bạn nói cụ thể hơn chút đc ko ? Mình cũng ko nắm vững các câu lệnh truy vấn phức tạp :(

  6. #6
    Ngày gia nhập
    04 2010
    Bài viết
    1,534

    Mặc định vấn đề INNER JOIN khi dữ liệu rỗng

    Mấy câu hỏi này thuần túy là truy xuất SQL, đem hỏi ở C# là làm sao gặp đúng người trả lời được. Nếu tôi là cao thủ SQL nhưng dốt về C#, tôi đâu có ghé box này làm gì!

    Chẳng rõ mấy cái tables có gì cho nên không trả lời cụ thể được. Tuy nhiên, theo vd kết quả thì dùng JOIN trong trường hợp này là sai. Đúng thì phải lập câu lệnh xuất tên PB và 12 cột, mỗi cột là SUM của số NV.

  7. #7
    Ngày gia nhập
    05 2010
    Bài viết
    505

    Trích dẫn Nguyên bản được gửi bởi VoTichSu Xem bài viết
    Mấy câu hỏi này thuần túy là truy xuất SQL, đem hỏi ở C# là làm sao gặp đúng người trả lời được. Nếu tôi là cao thủ SQL nhưng dốt về C#, tôi đâu có ghé box này làm gì!

    Chẳng rõ mấy cái tables có gì cho nên không trả lời cụ thể được. Tuy nhiên, theo vd kết quả thì dùng JOIN trong trường hợp này là sai. Đúng thì phải lập câu lệnh xuất tên PB và 12 cột, mỗi cột là SUM của số NV.
    yeah, do làm C# nên quen post vào đây. Về table thì có 3 trường cần quan tâm là phongBan, ngayVaoCty và ngayNghi pac ạ. Pac có cao kiến gì xin chỉ giáo.
    Thanks

  8. #8
    Ngày gia nhập
    04 2010
    Bài viết
    1,534

    Trích dẫn Nguyên bản được gửi bởi luxubu Xem bài viết
    Về table thì có 3 trường cần quan tâm là phongBan, ngayVaoCty và ngayNghi
    Thanks
    Bao nhiêu đây chi tiết không đủ. Đây là một báo cáo liệt kê sô nhân viên của từng phàng ban, như vậy chi tiết quan trọng nhất là liên hệ giữa Nhân Viên và Phòng Ban như thế nào.

    Đoán chừng theo lô gic thiết kế thông thường (nếu thiết kế của bạn siêu quá thì chịu)

    Code:
    SELECT pb.phongBan
    , thang1 = (select count(*) FROM bangNV nv WHERE nv.phongBan = pb.phongBan 
                     AND nv.ngayVaoCty < '20110201' AND (nv.ngayNghi >= '20110201' OR nv.ngayNghi IS NULL)
    , thang2 = (select count(*) FROM bangNV nv WHERE nv.phongBan = pb.phongBan 
                     AND nv.ngayVaoCty < '20110301' AND (nv.ngayNghi >= '20110301' OR nv.ngayNghi IS NULL)
    , thang3 = (select count(*) FROM bangNV nv WHERE nv.phongBan = pb.phongBan 
                     AND nv.ngayVaoCty < '20110401' AND (nv.ngayNghi >= '20110401' OR nv.ngayNghi IS NULL)
    , .........
    , thang12 = (select count(*) FROM bangNV nv WHERE nv.phongBan = pb.phongBan 
                     AND nv.ngayVaoCty < '20120101' AND (nv.ngayNghi >= '20120101' OR nv.ngayNghi IS NULL)
    FROM bangPB pb

  9. #9
    Ngày gia nhập
    08 2011
    Nơi ở
    Hà Nội | http://ipmac.vn
    Bài viết
    198

    Trích dẫn Nguyên bản được gửi bởi luxubu Xem bài viết
    yeah, do làm C# nên quen post vào đây. Về table thì có 3 trường cần quan tâm là phongBan, ngayVaoCty và ngayNghi pac ạ. Pac có cao kiến gì xin chỉ giáo.
    Thanks
    Với yêu cầu của bạn mình sẽ nghiên cứu dùng PIVOT table.
    Ví dụ thực tế của tớ trong hệ CRM nhé: cần lấy về đánh giá xếp hạng của khách hàng theo từng tháng của năm 2011 thì sẽ viết như bên dưới.

    Code:
    select *
    from ( 
     select GradeID, CustomerCode , MONTH(CreatedDate) AS Month from CustomerDetails
    where YEAR(CreatedDate) = 2011 
    )  DataTable
    PIVOT
    (
    	COUNT(CustomerCode)
    	FOR Month
    	IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
    )
    PivotTable
    Trường hợp của bạn thì phòng ban tương đương với GradeID trong câu lệnh trên.
    Bao chàng trai không tiếc tuổi xuân đang viết nhiều chương trình
    Em đẹp xinh cũng quyết lập công chưa muốn lấy chồng
    http://ipmac.vn/ <- Học lập trình ... sư
    http://laptrinh.tv/ <- Kênh chia sẻ video học IT
    http://www.youtube.com/user/anhnt3 <- Video thực hành lập trình... sư từ A-Z

  10. #10
    Ngày gia nhập
    05 2010
    Bài viết
    505

    Cảm ơn các pac đã nhiệt tình giúp đỡ. Mai mình sẽ thử 2 gợi ý trên, tuy nhiên mình thấy phát sinh thêm 1 vấn đề. Hiện tại các query trên đếm số nhân viên của 1 phòng ban dựa vào ngayVaoCty và ngayNghi, tuy nhiên thực tế lại có trường hợp ví dụ nhân viên Nguyễn Văn A tháng 3 thì ở phòng Kinh Doanh, sau đó tháng 4 lại chuyển sang phòng Kế Toán. Khi đó nếu ở các tháng sau thực hiện các query trên thì nó luôn tính Nguyễn Văn A là ở phòng Kinh Doanh, kể các các tháng 3 trở về trc vì luôn thỏa mã điều kiện ngayVaoCty và ngayNghi .
    Giờ phải điều chỉnh CSDL thế nào để có đc 1 thống kê đúng nhỉ ?
    Thanks

Các đề tài tương tự

  1. Algorithm Join 3 bảng lại với nhau sử dụng LinQtoSQL??
    Gửi bởi zoro_bka trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 3
    Bài viết cuối: 11-04-2011, 10:20 PM
  2. ADO.NET Left join trong LINQ có tác dụng gì?
    Gửi bởi GaPro trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 6
    Bài viết cuối: 11-03-2011, 11:50 PM
  3. LEFT OUTER JOIN | RIGHT OUTER JOIN | Giúp mình?
    Gửi bởi trung trong diễn đàn Thắc mắc đại cương Database & Reporting
    Trả lời: 2
    Bài viết cuối: 06-12-2009, 09:23 PM
  4. Không hiển thị đc cột khóa chính khi inner join!!!
    Gửi bởi icde trong diễn đàn Thắc mắc Microsoft SQL Server & Microsoft Access
    Trả lời: 3
    Bài viết cuối: 23-05-2009, 02:18 PM
  5. [Solved]hỏi về : Group by, natural join, inner join, constraint, trong SQL SERver 2
    Gửi bởi DESHWITAT LORD RUBICH trong diễn đàn Thắc mắc đại cương Database & Reporting
    Trả lời: 1
    Bài viết cuối: 19-10-2007, 04:28 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn