2011-07-19 4 views
2

月次出席のためのMySQLのピボットテーブルクエリを使用して、私は月次レポートのピボットクエリを使用していた。..レポート

私の表は、このようなものです:月次出席報告書については

CREATE TABLE IF NOT EXISTS `attendance` (
    `empID` int(11) NOT NULL, 
    `date` date NOT NULL, 
    `deptID` int(11) NOT NULL, 
    `attStatus` varchar(3) NOT NULL, 
    PRIMARY KEY (`empID`,`date`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

、私はこのクエリを使用しています:

SELECT empID, 
    GROUP_CONCAT(if(DAY(`date`) = 1, `attStatus`, NULL)) AS 'day1', 
    GROUP_CONCAT(if(DAY(`date`) = 2, `attStatus`, NULL)) AS 'day2', 
    GROUP_CONCAT(if(DAY(`date`) = 3, `attStatus`, NULL)) AS 'day3', 
    GROUP_CONCAT(if(DAY(`date`) = 4, `attStatus`, NULL)) AS 'day4', 
    GROUP_CONCAT(if(DAY(`date`) = 5, `attStatus`, NULL)) AS 'day5', 
    GROUP_CONCAT(if(DAY(`date`) = 6, `attStatus`, NULL)) AS 'day6', 
    GROUP_CONCAT(if(DAY(`date`) = 7, `attStatus`, NULL)) AS 'day7', 
    GROUP_CONCAT(if(DAY(`date`) = 8, `attStatus`, NULL)) AS 'day8', 
    GROUP_CONCAT(if(DAY(`date`) = 9, `attStatus`, NULL)) AS 'day9', 
    GROUP_CONCAT(if(DAY(`date`) = 10, `attStatus`, NULL)) AS 'day10', 
    GROUP_CONCAT(if(DAY(`date`) = 11, `attStatus`, NULL)) AS 'day11', 
    GROUP_CONCAT(if(DAY(`date`) = 12, `attStatus`, NULL)) AS 'day12', 
    GROUP_CONCAT(if(DAY(`date`) = 13, `attStatus`, NULL)) AS 'day13', 
    GROUP_CONCAT(if(DAY(`date`) = 14, `attStatus`, NULL)) AS 'day14', 
    GROUP_CONCAT(if(DAY(`date`) = 15, `attStatus`, NULL)) AS 'day15', 
    GROUP_CONCAT(if(DAY(`date`) = 16, `attStatus`, NULL)) AS 'day16', 
    GROUP_CONCAT(if(DAY(`date`) = 17, `attStatus`, NULL)) AS 'day17', 
    GROUP_CONCAT(if(DAY(`date`) = 18, `attStatus`, NULL)) AS 'day18', 
    GROUP_CONCAT(if(DAY(`date`) = 19, `attStatus`, NULL)) AS 'day19', 
    GROUP_CONCAT(if(DAY(`date`) = 20, `attStatus`, NULL)) AS 'day20', 
    GROUP_CONCAT(if(DAY(`date`) = 21, `attStatus`, NULL)) AS 'day21', 
    GROUP_CONCAT(if(DAY(`date`) = 22, `attStatus`, NULL)) AS 'day22', 
    GROUP_CONCAT(if(DAY(`date`) = 23, `attStatus`, NULL)) AS 'day23', 
    GROUP_CONCAT(if(DAY(`date`) = 24, `attStatus`, NULL)) AS 'day24', 
    GROUP_CONCAT(if(DAY(`date`) = 25, `attStatus`, NULL)) AS 'day25', 
    GROUP_CONCAT(if(DAY(`date`) = 26, `attStatus`, NULL)) AS 'day26', 
    GROUP_CONCAT(if(DAY(`date`) = 27, `attStatus`, NULL)) AS 'day27', 
    GROUP_CONCAT(if(DAY(`date`) = 28, `attStatus`, NULL)) AS 'day28', 
    GROUP_CONCAT(if(DAY(`date`) = 29, `attStatus`, NULL)) AS 'day29', 
    GROUP_CONCAT(if(DAY(`date`) = 30, `attStatus`, NULL)) AS 'day30', 
    GROUP_CONCAT(if(DAY(`date`) = 31, `attStatus`, NULL)) AS 'day31', 
    COUNT(if(`attStatus`='P', `attStatus`, NULL)) AS 'totalP' 
FROM `attendance` 
WHERE deptID=1 AND `date` BETWEEN '2011-07-01' AND '2011-07-31' 
GROUP BY empID 

私の質問は、このクエリが長すぎますか? 毎月の出席レポートを表示するためのこのクエリの代替手段はありますか?

このクエリが正常であれば、30日以内の月には31日間の結果が表示されます。これには何か解決策はありますか?元のクエリが動作しますが、このようなものは単純であるかどう

enter image description here

+0

をuがこの http://dba.stackexchange.com/questions/45995/display-monthly-attendance-report-in-を試すために私は、このソリューションを得ましたmysql – Surendra

+0

この投稿はあなたの質問に関連しています: https://stackoverflow.com/questions/13042710/mysql-count-everyday-in-a-month-returns-blob-2b-instead-of-number –

答えて

0

ないアイデア:

UPDATE:

ここでは、私がしたいレポートの種類を説明スクリーンショットです。

select DAY(date),count(*) from attendance where MONTH(date) = 2 group by DAY(date); 

これは2月の出席者を取得する必要があります。出力は次のようになります。

+-----------+----------+ 
| DAY(date) | count(*) | 
+-----------+----------+ 
|  18 |  1 | 
|  19 |  2 | 
+-----------+----------+ 
+0

実際には、 'attStatus'列に 'P'、 'A'、 'WO'、 'M'などの値を含めることを忘れていて、毎日のステータスをレポートに表示したい... –

+0

どうしますか一日のattStatusのステータスを表示しますか?出席者ごとに1つずつあり、1日に出席者の統計をグループ化していますか?あなたが質問に –

+0

という質問にあなたの意図したレポートの出力を投稿したなら、私はアップデートを投稿しました。私はこの種のレポートを使用したいです..このクエリは正常に動作しますが、代替の短いクエリを使用できますか? –

0

まず、ヘルプ表を作成します。

CREATE TABLE days 
(d TINYINT PRIMARY KEY 
) ; 

INSERT INTO days 
VALUES 
(0), (1), (2), ..., (31) ; 

その後、あなたはこれを試すことができます。これは、しかし、あなたのクエリよりも少ない列を返します。

SELECT 
    a.empID 
    , GROUP_CONCAT(CASE WHEN a.attStatus IS NULL 
          THEN 'N' 
          ELSE a.attStatus 
        END 
        ORDER BY dates.dateCheck) 
    AS days 
    , COUNT(CASE WHEN a.attStatus='P' THEN 1 END) 
    AS totalP 
FROM 
    (SELECT monthStart + INTERVAL d DAY 
      AS dateCheck 
     FROM days 
     CROSS JOIN 
      (SELECT '2011-07-01' AS monthStart 
     ) AS m 
     WHERE MONTH(monthStart + INTERVAL d DAY) = MONTH(monthStart) 
    ) AS dates 
    LEFT JOIN attendance AS a 
    ON a.`date` = dates.dateCheck 
WHERE a.deptID = 1 
GROUP BY a.empID 
関連する問題