Statistics by day and month (php) - php

I want to make statistics for my website by days and month & years
I think to make date() function
Well, First I create a database that has 3 col
Id
date
statistics
For example today we are 27-05-2016, So, the database has
1 | 27-05-2016 | 5
and when I have a new day that insert a new row for example
2 | 28-05-2016 | 20
and I showed result with while ... etc
but I have a problem I want to know how when the day finished I insert new day ? How I can Automatically if the day ended I insert new date for the new day ?

Get the latest date from database, SELECT * FROM stat_table ORDER BY date DESC;
Keep latest date in a variable $latest_date = $data['date'];
if (current_date = $latest_date) {
update database
} else {
insert new row
}

I am not too good with php but im pretty sure the best you can do is wait for an interaction(logging in ect), and then check the time and compare it with the last logged time. So for example. jDoe787 logged in at 6:56 AM 1/5/16 the logges right back out.(Here the server updates the last time someone logged in) jDoe logs in later at 12:01 AM, a script turns on as a it is a different day then the one he last logged so it changes the database to the new day, and does whatever it needs to

Try to use REPLACE INTO operator. But first you have to make a UNIQUE index on your DATE field

Always run the update query with current date and if the update returns false then insert the new entry

I guess you want a table with one row for each distinct date, and you want to update your statistics column with new data.
You can do this cleanly in MySQL, using some MySQL-specific extensions.
First, you create your table and put a UNIQUE INDEX on your date column. This kind of table definition does the trick. (This is standard SQL.)
CREATE TABLE `stat` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`date` DATE NOT NULL,
`statistics` INT(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `date_index` (`date`)
);
Notice that, with this definition, an attempt to INSERT a duplicate date value will fail. But that's good, because MySQL has the INSERT ... ON DUPLICATE KEY UPDATE... syntax. (This is MySQL-specific.)
To insert a new row for the current date if necessary, and otherwise to add one to the current date's statistics column, you can use this statement:
INSERT INTO stat (date,statistics) VALUES (CURDATE(), 1)
ON DUPLICATE KEY UPDATE statistics = statistics+1;
The first line of this statement creates a row in the stat table and sets the statistics column to 1. The second line increments statistics if the row already exists.
Notice one other thing: the id column is not strictly necessary. You can use the date column as the primary key. This table definition will work well for you.
CREATE TABLE `stat` (
`date` DATE NOT NULL,
`statistics` INT(11) NOT NULL,
PRIMARY KEY (`date`)
);

Related

PHP & MySQL - Generate own unique reference

I am currently coding a web application which I will need to create unique reference for quotes and invoices.
I wanted to create a reference that included the year and month then an reference number. i.e YYYY-MM-001.
The web application will be multi tenant and several users will be using it at the same time. One of my concerns is, how would I generate my reference without it be duplicated at the same time if there is multiple users doing the same request at the same time?
What would be the best way for me to approach this?
I am using PHP 8 and a MySQL database.
You can use the primary key id or any unique column, then don't worry about the uniqueness of the data.
Use that column/id to generate a unique reference as follows :
update invoices
set reference = concat(date_format(now(), "%Y-%m-00"), unique_id)
where unique_id = 1;
If you're sure you won't have more than 999 quotes/invoices in one month, you could do something like the following...
CREATE TABLE quotes (
id INT(14) NOT NULL AUTO_INCREMENT,
YMFqid char(11) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY (YMFqid));
CREATE TABLE YMnext (
YM char(7) NOT NULL,
next INT(3) NOT NULL DEFAULT 0,
PRIMARY KEY (YM));
Then to get the next values, you'll need some queries like...
SELECT next AS latest FROM YMnext WHERE YM = '2022-12';
INSERT INTO YMnext VALUES ('2022-12', 0);
UPDATE YMnext SET next = next + 1 WHERE YM = '2022-12' AND next = latest;
If the SELECT fails, then you insert, otherwise you update AND check that one and only one row was updated. If there's a chance you could have more than 999 quotes in a month, then you can alter the column sizes accordingly.

How to insert value into table if NULL? - MySql

I am trying to insert into a column if the column value is not null.
I have my table:
create table clock(
usr_id int,
clock_id int AUTO_INCREMENT,
clock_in date,
clock_in_time time,
clock_out date,
clock_out_time time,
FOREIGN KEY (usr_id)references df_user(usr_id),
primary key(clock_id)
);
I am trying to grab the last entry of the table and checking whether or not it is null.
SET #lastEntry = (SELECT clock_id FROM clock WHERE clock_id=(SELECT max(clock_id) FROM clock));
SET #clock_value = (select clock_out from clock where clock.clock_id = #lastEntry);
If the last entries clock out column is NULL (#clock_value IS NULL) then insert into the table.
if #clock_value IS NULL THEN insert into clock (clock_out, clock_out_time) values (curdate(), curtime());
Can someone please tell me the correct way of doing this process? SQL is telling me that the query is wrong. Thanks all!
What you need seems to be an update clause.
update clock set clock_out=curdate(), clock_out_time=curtime() ;
or something like that. You cannot insert here, because when inserting you create new rows.

MySQL trigger when today's date matches due date

I'm developing an application in CakePHP 2.4.7
I have my MySQL database and I've come to the necessity of triggering an update when the system's date and hour matches a due date I have in a table.
The table I'm using is the following
CREATE TABLE applied_surveys (id CHAR(36) NOT NULL PRIMARY KEY,
display_name VARCHAR(200),
area_id CHAR(36) NOT NULL,
survey_id CHAR(36) NOT NULL,
system_user_id CHAR(36) NOT NULL,
code VARCHAR(50),
init_date DATE,
due_date DATE,
init_hour TIME,
due_hour TIME,
completed INT,
state TINYINT DEFAULT 1,
max_responders INT,
created DATE, modified DATE,
FOREIGN KEY (area_id) REFERENCES areas(id),
FOREIGN KEY (survey_id) REFERENCES surveys(id),
FOREIGN KEY (system_user_id) REFERENCES system_users(id));
As you can see, I'm using an init date/hour and a due date/hour. My intention here is that I add a survey and I set a due date. When the due date and hour are reached the system must change my status(state) value to 0, meaning that the survey has been closed.
I'm integrating this database to a CakePHP application, but I'm not really sure where I should program the logic for this situation.
You don't necessarily need to update the column, you can simply return the comparison of the current system date and time with the due_date and due_time when the table is queried.
The separation of due_date and due_hour into two separate columns seems a bit odd, if we assume that neither of those will be null, we can convert those into a DATETIME, and then compare to NOW()
e.g.
SELECT NOW() <= CONCAT(s.due_date,' ',s.due_hour) AS `state`
FROM applied_surveys s
A MySQL row trigger gets fired when a row is modified. MySQL triggers don't get fired when the system clock advances.
You could run an UPDATE statement that identifies rows to be updated whenever you wanted, e.g.
UPDATE applied_surveys s
SET s.state = 0
WHERE NOW() >= CONCAT(s.due_date,' ',s.due_hour)
AND NOT (s.state <=> 0)
You can't write "sistem", it's system.
You will need to run a cron job every second/minute/hour, or whatever you prefer, that would check each record and see which ones are later than the system date. You can't expect it to run exactly at the time the dates become exactly the same, especially if you account for the seconds.
You can read about CRON jobs here : http://code.tutsplus.com/tutorials/managing-cron-jobs-with-php--net-19428
You can use events rather than triggers.
A stored procedure is only executed when it is invoked directly; a trigger is executed when an event associated with a table such as an insert, update or delete event occurs while an event can be executed at once or more regular intervals.
To set up events
SET GLOBAL event_scheduler = ON;
CREATE EVENT IF NOT EXISTS update_state
ON SCHEDULE EVERY 1 day
DO
Update applied_surveys
Set state= 0
where due_date < curdate();
//similar condition can be added for hour.
To see all events in the schema
SHOW EVENTS;

MYSQL QUERY to retrieve the data

I have the following schema with the following attributes:
USER(TABLE_NAME)
USER_ID|USERNAME|PASSWORD|TOPIC_NAME|FLAG1|FLAG2
I have 2 questions basically:
How can I make an attribute USER_ID as primary key and it should
automatically increment the value each time I insert the value into
the database.It shouldn't be under my control.
How can I retrieve a record from the database, based on the latest
time from which it was updated.( for example if I updated a record
at 2pm and same record at 3pm, if I retrieve now at 4pm I should get
the record that was updated at 3pm i.e. the latest updated one.)
Please help.
I'm assuming that question one is in the context of MYSQL. So, you can use the ALTER TABLE statement to mark a field as PRIMARY KEY, and to mark it AUTOINCREMENT
ALTER TABLE User
ADD PRIMARY KEY (USER_ID);
ALTER TABLE User
MODIFY COLUMN USER_ID INT(4) AUTO_INCREMENT; -- of course, set the type appropriately
For the second question I'm not sure I understand correctly so I'm just going to go ahead and give you some basic information before giving an answer that may confuse you.
When you update the same record multiple times, only the most recent update is persisted. Basically, once you update a record, it's previous values are not kept. So, if you update a record at 2pm, and then update the same record at 3pm - when you query for the record you will automatically receive the most recent values.
Now, if by updating you mean you would insert new values for the same USER_ID multiple times and want to retrieve the most recent, then you would need to use a field in the table to store a timestamp of when each record is created/updated. Then you can query for the most recent value based on the timestamp.
I assume you're talking about Oracle since you tagged it as Oracle. You also tagged the question as MySQL where the approach will be different.
You can make the USER_ID column a primary key
ALTER TABLE <<table_name>>
ADD CONSTRAINT pk_user_id PRIMARY KEY( user_id );
If you want the value to increment automatically, you'd need to create a sequence
CREATE SEQUENCE user_id_seq
START WITH 1
INCREMENT BY 1
CACHE 20;
and then create a trigger on the table that uses the sequence
CREATE OR REPLACE TRIGGER trg_assign_user_id
BEFORE INSERT ON <<table name>>
FOR EACH ROW
BEGIN
:new.user_id := user_id_seq.nextval;
END;
As for your second question, I'm not sure that I understand. If you update a row and then commit that change, all subsequent queries are going to read the updated data (barring exceptionally unlikely cases where you've set a serializable transaction isolation level and you've got transactions that run for multiple hours and you're running the query in that transaction). You don't need to do anything to see the current data.
(Answer based on MySQL; conceptually similar answer if using Oracle, but the SQL will probably be different.)
If USER_ID was not defined as a primary key or automatically incrementing at the time of table creation, then you can use:
ALTER TABLE tablename MODIFY USER_ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT;
To issue queries based on record dates, you have to have a field defined to hold date-related datetypes. The date and time of record modifications would be something you would manage (e.g. add/change) based on the way in which you are accessing the records (some PHP-related way? it's unclear what scripts you have in play, based on your question.) Once you have dates in your records you can ORDER BY the date field in your SELECT query.
Check this out
For your AUTOINCREMENT, Its a question already asked here
For your PRIMARY KEY use this
ALTER TABLE USER ADD PRIMARY KEY (USER_ID)
Can you provide more information. If the value gets updated you definitely do NOT have your old value that you entered at 2pm present in the dB. So querying for it will be fine
You can use something like this:
CREATE TABLE IF NOT EXISTS user (
USER_ID unsigned int(8) NOT NULL AUTO_INCREMENT,
username varchar(25) NOT NULL,
password varchar(25) NOT NULL,
topic_name varchar(100) NOT NULL,
flag1 smallint(1) NOT NULL DEFAULT 0,
flag2 smallint(1) NOT NULL DEFAULT 0,
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
For selection use query:
SELECT * from user ORDER BY update_time DESC

Unique Identifier Mixed Format with Date Prefix (Php / MySQL)

I am creating a ticketing system that will keep track of tickets that a customer creates. The ticket's basic information will be stored in a table 'tickets' who's structure is as follows:
Primary Key (int 255)
Ticket_Key (varchar)
Ticket Number (varchar 500)
Label
Date Created
Delete
and so on..
The issue is that there will eventually be a large amount of tickets and we need a more uniform way of identifying tickets. I would like PHP to create a Ticket Number in the ticket number that will contain mixed values. The date (in format 20111107), followed by a auto incremented value 1001. 1002, 1003, ...). So the Ticket Number will be 201111071001 for an example.
The issue is how do I program this in PHP to insert to the MySQL database? Also, how do I prevent the possibility of duplicate values in the Unique Id in PHP? There will be a very large amount of customers using the table to insert records.
What about using an auto-increment and combining this with the date field to generate a sequence number for that date and hence a ticketId.
So your insert process would be something like this:
INSERT INTO table (...ticket info...)
You would then retrieve the auto-increment for this row and run a query like this
UPDATE table SET sequence = (SELECT ($id-MAX(auto_increment)) FROM table WHERE date_created=DATE_SUB(CURDATE(),INTERVAL 1 DAY)) WHERE auto_increment=$id
You could then easily create a ticketId of format YYYMMDDXXXX. Assuming you never retro-add tickets in the past this would only ever require these two queries even under heavy usage.
[EDIT] Actually, after looking into this there is a much better way to do this natively in MySQL. If you define two columns (date and sequence) and make them a primary key (both columns) with the sequence field as an auto-increment then MySQL will update the sequence column as an auto-increment per date (i.e. it will start with value 1 for each date).
[EDIT] A table structure along these lines would do the job for you:
CREATE TABLE IF NOT EXISTS `table` (
`created_date` date NOT NULL,
`ticket_sequence` int(11) NOT NULL auto_increment,
`label` varchar(100) NOT NULL,
[other fields as required]
PRIMARY KEY (`created_date`,`ticket_sequence`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
When retrieving the data you could then do something like
SELECT CONCAT( DATE_FORMAT(created_date,'%Y%m%d'),LPAD(ticket_sequence,4,'0')) AS ticket_number, other fields.... FROM table
as i understand that you want to make one result of two different fields like datefield and ticketnumfield
in mysql you do this through the command:
SELECT concat( datefield, ticketnumfeild ) FROM `tbl_name`
this query return the result like 201111071001
I did something like this before where I wanted to refresh the counter for each new day. Unfortunately I do not speak PHP so you will have to settle for explanation and maybe some pseudo code.
Firstly, create a couple of fields in a config file to keep track of your counter. This should be a date field and a number fields...
LastCount (Number)
LastCountDate (Date)
Then you make sure that your ticket number field in your database table is set to only unique values, so it throws an error if you try to insert a duplicate.
Then in your code, you load your counter values (LastCount and LastCountDate) and you process them like so...
newCount = LastCount;
if LastCountDate == Today
increment newCount (newCount++)
else
reset newCount (newCount = 1)
you can then use newCount to create your ticket number.
Next, when you try to insert a row, if it is successful, then great. If it fails, then you need to increment newCount again, then try the insert again. Repeat this until the insert is successful (put it in a loop)
Once you have successfully inserted the row, you need to update the database with the Count Values you just used to generate the ticket number - so they are ready for use the next time.
Hope that helps in some way.

Categories