Tampilkan Laporan Kehadiran Bulanan di MySql


8

Saya sedang melakukan Sistem Manajemen Sekolah di php menggunakan DB Mysql. Saya terjebak dalam Proyek saya. Tolong ada yang menyarankan apa yang saya lakukan salah.

Saya memiliki dua tabel di database saya; satu untuk menyimpan Studentscatatan satu lagi untuk menyimpan attendancehari mereka dengan bijak

Sekarang saya ingin menampilkan laporan semua siswa di kelas tertentu untuk bulan ini apakah mereka hadir atau tidak. Tapi saya hanya menangkap rincian siswa Absen hanya di meja hadir.

Saya telah menulis kueri sql untuk menampilkan hasilnya di sini adalah:

SELECT tab.class, attend, DATE, ta.rollno, ta.StdNm 
FROM tbl_absentees tab, tbl_admission ta
WHERE ta.Cls = class
  AND ta.rollno = tab.rollno
  AND class =22
  AND attend =  'A'
  AND DATE =  '2013-06-07';

Hasilnya adalah:

Class Attend RollNo StudentName

Tapi saya ingin menampilkan tabel 31 hari dengan mengambil hanya Tanggal dalam tabel kehadiran jika hadir = Tampilan A untuk hari-hari yang tidak hadir jika tidak Tampilkan 'P' untuk hari yang tersisa

Bagaimana saya bisa melakukan ini di mysql? Adakah yang bisa menyarankan / memberi saya ide untuk mencapai ini.

Maaf atas kesalahan klasifikasi dalam pertanyaan saya. Sebenarnya saya ingin menampilkan laporan kehadiran untuk bulan tertentu di mana data berasal dari dua tabel:

  • tabel pertama terdiri dari StudentName, RollNo, Class
  • tabel kedua terdiri dari Tanggal, Status, RollNo, Kelas

Sekarang saya ingin menampilkan laporan seperti ini .

Jawaban:


18

Jenis rotasi data dari kolom ke baris dikenal sebagai PIVOT. MySQL tidak memiliki fungsi pivot tetapi Anda dapat menggunakan fungsi agregat dengan ekspresi KASUS untuk mendapatkan hasilnya.

Saran pertama saya adalah menentukan apakah Anda memiliki calendartabel atau tabel yang berisi semua tanggal yang ingin Anda tampilkan. Jika tidak, maka saya sarankan untuk membuat yang serupa dengan yang berikut:

CREATE TABLE calendar (`Date` datetime) ;

INSERT INTO calendar (`Date`)
VALUES
    ('2013-06-01 00:00:00'),
    ('2013-06-02 00:00:00'),
    ('2013-06-03 00:00:00'),
    ('2013-06-04 00:00:00'),
    ('2013-06-05 00:00:00'),
    ('2013-06-06 00:00:00'),
    ('2013-06-07 00:00:00'),
    ('2013-06-08 00:00:00'),
    ('2013-06-09 00:00:00'),
    ('2013-06-10 00:00:00');

Ini memungkinkan Anda membuat daftar semua tanggal yang ingin Anda tampilkan.

Kedua, Anda perlu membuat daftar setiap siswa dan setiap tanggal. Anda bisa melakukan ini dengan menggunakan CROSS JOIN antara Anda tbl_admissiondan calendartabel:

select c.date, a.studentname, a.rollno, a.class
from calendar c
cross join tbl_admission a;

Lihat Demo . Setelah Anda memiliki daftar ini, maka Anda dapat menggunakan LEFT JOIN ke tbl_absenteestabel Anda yang ada untuk mendapatkan hasilnya:

select 
  ca.studentname,
  ca.rollno,
  ca.class,
  max(case when ca.date = '2013-06-01' then coalesce(p.status, 'P') end) `2013-06-01`,
  max(case when ca.date = '2013-06-02' then coalesce(p.status, 'P') end) `2013-06-02`,
  max(case when ca.date = '2013-06-03' then coalesce(p.status, 'P') end) `2013-06-03`,
  max(case when ca.date = '2013-06-04' then coalesce(p.status, 'P') end) `2013-06-04`,
  max(case when ca.date = '2013-06-05' then coalesce(p.status, 'P') end) `2013-06-05`,
  max(case when ca.date = '2013-06-06' then coalesce(p.status, 'P') end) `2013-06-06`,
  max(case when ca.date = '2013-06-07' then coalesce(p.status, 'P') end) `2013-06-07`,
  max(case when ca.date = '2013-06-08' then coalesce(p.status, 'P') end) `2013-06-08`,
  max(case when ca.date = '2013-06-08' then coalesce(p.status, 'P') end) `2013-06-09`,
  max(case when ca.date = '2013-06-10' then coalesce(p.status, 'P') end) `2013-06-10`
from
(
  select c.date, a.studentname, a.rollno, a.class
  from calendar c
  cross join tbl_admission a
) ca
left join tbl_absentees p
  on ca.rollno = p.rollno
  and ca.date = p.date
group by ca.studentname, ca.rollno, ca.class
order by ca.rollno;

Lihat SQL Fiddle dengan Demo . Tentu saja untuk permintaan Anda, kemungkinan besar Anda ingin menanyakan data berdasarkan rentang tanggal sehingga Anda tidak ingin membuat hard-code nilai-nilainya. Jika itu masalahnya, maka Anda perlu melihat menggunakan pernyataan yang disiapkan untuk menghasilkan SQL dinamis:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(CASE WHEN ca.date = ''',
      date_format(date, '%Y-%m-%d'),
      ''' THEN coalesce(p.status, ''P'') END) AS `',
      date_format(date, '%Y-%m-%d'), '`'
    )
  ) INTO @sql
FROM calendar
where date>='2013-06-01'
  and date <= '2013-06-05';

SET @sql 
  = CONCAT('SELECT ca.studentname,
              ca.rollno,
              ca.class, ', @sql, ' 
            from
            (
              select c.date, a.studentname, a.rollno, a.class
              from calendar c
              cross join tbl_admission a
            ) ca
            left join tbl_absentees p
              on ca.rollno = p.rollno
              and ca.date = p.date
            where ca.date>=''2013-06-01''
              and ca.date <= ''2013-06-05''
            group by ca.studentname, ca.rollno, ca.class
            order by ca.rollno');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Lihat SQL Fiddle dengan Demo . Kedua pertanyaan ini akan memberikan hasil yang mirip dengan:

| STUDENTNAME | ROLLNO | CLASS | 2013-06-01 | 2013-06-02 | 2013-06-03 | 2013-06-04 | 2013-06-05 | 2013-06-06 | 2013-06-07 | 2013-06-08 | 2013-06-09 | 2013-06-10 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------
|       Naren |      1 |    22 |          A |          A |          A |          A |          P |          P |          P |          P |          P |          P |
|       Srinu |      2 |    22 |          P |          P |          P |          P |          P |          P |          P |          P |          P |          P |
|        Blah |      3 |    22 |          A |          P |          P |          P |          P |          P |          P |          P |          P |          P |
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.