MySqlで月次出席レポートを表示する


8

Mysql DBを使用して、phpで学校管理システムを実行しています。プロジェクトで立ち往生しています。誰かが私が間違っていることを提案してください。

データベースに2つのテーブルがあります。1つはStudentsレコードを保存すること、もう1つはattendance日ごとに保存することです

今、私は今月の特定のクラスのすべての学生のレポートを表示したいと思います。ただし、欠席している学生の詳細のみを出席表でのみキャプチャしています。

ここに結果を表示するSQLクエリを作成しました。

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';

結果は次のとおりです。

Class Attend RollNo StudentName

しかし、出席= Aの場合は出席表の日付のみを取り、31日の表の方法で表示したいのですが、欠席の場合はAを表示し、それ以外の場合は残りの日には「P」を表示します

mysqlでこれを行うにはどうすればよいですか?誰かがこれを達成するためのアイデアを私に提案/提供できますか?

私の質問を誤解して申し訳ありません。実際には、データが2つのテーブルから取得される特定の月の出席レポートを表示したいと思います。

  • 最初のテーブルは、StudentName、RollNo、Classで構成されています
  • 2番目のテーブルは、日付、ステータス、RollNo、クラスで構成されます

このようなレポートを表示したいのですが。

回答:


18

このタイプのデータの列から行へのローテーションは、PIVOTと呼ばれます。MySQLにはピボット関数はありませんが、CASE式で集計関数を使用して結果を取得できます。

私の最初の提案はcalendar、表示する日付のすべてを含むテーブルまたはテーブルがあるかどうかを判断することです。そうでない場合は、次のようなものを作成することをお勧めします。

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');

これにより、表示するすべての日付のリストを生成できるようになります。

次に、各学生と各日付のリストを生成する必要があります。あなたとあなたtbl_admissioncalendarテーブルの間にCROSS JOINを使うことでこれを行うことができます:

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

デモを参照してください。このリストtbl_absenteesを取得したら、既存のテーブルにLEFT JOINを使用して結果を取得できます。

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;

SQL Fiddle with Demoを参照してください。もちろん、リクエストの場合は、日付範囲に基づいてデータをクエリする可能性が高いため、値をハードコーディングする必要はありません。その場合は、準備済みステートメントを使用して動的SQLを生成する方法を確認する必要があります。

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;

SQL Fiddle with Demoを参照してください。これらのクエリはどちらも、次のような結果になります。

| 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 |
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.