简体   繁体   中英

sum of total present values in a row in mysql

attendance table

id name 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 month year

 1 abcd P P P HOLIDAY P P P P P P HOLIDAY P P P P P P HOLIDAY P P P P P P HOLIDAY P P P P P P 01 2014

you can see above is a attendance table. a member abcd has attended all days in January month. so her total present days in January month is 27.

so in this table i want to add another field which will show total present days of the member of a particular month.

please tell me how can i count the number of present day (P) from this table.

CREATE TABLE `attendance` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `Ecode` varchar(100) NOT NULL,
 `Ename` varchar(100) NOT NULL,
 `01` varchar(200) NOT NULL,
 `02` varchar(200) NOT NULL,
 `03` varchar(200) NOT NULL,
 `04` varchar(200) NOT NULL,
 `05` varchar(200) NOT NULL,
 `06` varchar(200) NOT NULL,
 `07` varchar(200) NOT NULL,
 `08` varchar(200) NOT NULL,
 `09` varchar(200) NOT NULL,
 `10` varchar(200) NOT NULL,
 `11` varchar(200) NOT NULL,
 `12` varchar(200) NOT NULL,
 `13` varchar(200) NOT NULL,
 `14` varchar(200) NOT NULL,
 `15` varchar(200) NOT NULL,
 `16` varchar(200) NOT NULL,
 `17` varchar(200) NOT NULL,
 `18` varchar(200) NOT NULL,
 `19` varchar(200) NOT NULL,
 `20` varchar(200) NOT NULL,
 `21` varchar(200) NOT NULL,
 `22` varchar(200) NOT NULL,
 `23` varchar(200) NOT NULL,
 `24` varchar(200) NOT NULL,
 `25` varchar(100) NOT NULL,
 `26` varchar(200) NOT NULL,
 `27` varchar(200) NOT NULL,
 `28` varchar(200) NOT NULL,
 `29` varchar(200) NOT NULL,
 `30` varchar(200) NOT NULL,
 `31` varchar(200) NOT NULL,
 `total_p` varchar(200) NOT NULL,
 `total_sl` varchar(100) NOT NULL,
 `total_al` varchar(100) NOT NULL,
 `month` varchar(200) NOT NULL,
 `year` varchar(200) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=latin1

Your table definition will look something like this.

CREATE TABLE `attendance` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) ,
  `1` VARCHAR(10),
  `2` VARCHAR(10),
  `3` VARCHAR(10),
    ...
  `31` VARCHAR(10),
  `month` INT(11),
  `year` INT(11),
  PRIMARY KEY (`id`)
) 

Your p-counter expression will look like this in SQL

SELECT name,
       IF(`1`='P',1,0)+IF(`2`='P',1,0)+IF(`3`='P',1,0)+IF(`4`='P',1,0)+
        etc. etc. +IF(`31`='P',1,0) AS pcount,
       month,
       year
  FROM attendance

If this looks like a nasty expression, that's because it is. I hope you understand what a genuinely difficult-to-maintain table definition this is.

Edit One row per person per day would work much better. The attendance table might look like this:

 id          int
 name        varchar
 day         DATE
 attendance  varchar(10)

Then you could produce a report showing monthly attendance using conventional SQL aggregate reporting, something like this.

SELECT name, 
       DATE_FORMAT('%Y-%m-01') AS month_beginning,
       SUM(IF(attendance = 'P', 1, 0)) AS days_present
  FROM attendance
 GROUP BY name, DATE_FORMAT('%Y-%m-01')
 ORDER BY name, DATE_FORMAT('%Y-%m-01') 

Hello and welcome to stack overflow!

Yes there may be a better way to store your data, but it is easy to solve your problem. I am going to assume you already know how to get your $row variable, if not just leave a comment and I will tell you how. Having said that, the code goes like this:

$attendance = 0;

for ($index = 1;index <= 31;index++) {
    if ($row[' . strval($index) . '] === "P") {
        $attendance++;
    }
}

echo "Attendance is " . strval($attendance) . " days";

since i cant post a comment yet (bec. of required reputation) ill just post my suggestion here,

can you please show us the structure of your table? Try this command and kindly post the output.

  SHOW CREATE TABLE 'your attendance table Name'

(UPDATES) you need to change you table structure, you can create something like this, not normalize, but at least maybe this can help you.

 CREATE TABLE `attendance` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `Ecode` varchar(15) NOT NULL,
   `Ename` varchar(100) NOT NULL,
   `date`  DATE NOT NULL,
   `status` char(1) NOT NULL,
    PRIMARY KEY (`id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=latin1;

at status field, you try use P - present, H - holiday, A- absent... and your attendance table will look like this:

   ------------------------------------------------
     id  | Ecode | Ename    |  date     | status |
   -----------------------------------------------
     1   | code1 | Jane Doe |2014-01-05 | P
   -----------------------------------------------
     2   | code1 | Jane Doe |2014-01-06 | A   
   ----------------------------------------------
   ...

Then, you can query something like this:

 SELECT Ecode, Ename, count(status)  as numberOfpresent
 FROM attendance WHERE status = 'P'
 GROUP By Ecode;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM