How to insert value into table if NULL? - MySql - php

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.

Related

mysql insert and update table with max 3

I have a php script that logs inputs from a form into a mysql database table. I'm looking for a way to insert this data untill 3 rows are created, after which it has to update the existing rows so that the first one updates to the new input, the second one to the former first input and the third one to the former second input.
Table:
CREATE TABLE IF NOT EXISTS inputlog (
id int(11) NOT NULL auto_increment,
userid int(11) NOT NULL default '0',
name text,
value text,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;`
For the first three rows i use:
insert into inputlog (userid,name,value) values('$userid','$name','$value')
After that is has to become:
update inputlog set value = '$value' where userid = '$userid' and name = '$name'
where it has to update all the successive rows.
How can i accomplish this?
Too long for comments, so...
Looks like you want to have only 3 rows in your table because you want the data to be sorted by the id. So id=1 will be the latest value, then id=2 and finally id=3.
In short, do not do that, the id field can be any value. Do not code for that. The danger is if you use the id in another table as a foreign key, you will loose referential integrity. What I propose is:
Add an timestamp column for each row.
Every time you insert a new value, set the timestamp column to NOW()
When selecting, sort on the timestamp and limit to 3 results
If you MUST have only 3 rows, you can then delete the row except for the 3 most recent timestamps.
But... if you must do that...
perform a SELECT with the first 2 lines
truncate the table (delete all rows)
insert the new line, then the 2 stored lines
You will then ahve your 3 rows in the order you want. But without seeing the entire reasoning for your application, my "spider sense" tells me you will hit a wall later on...
And check the comments for other things to worry about.

Statistics by day and month (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`)
);

key violation when inserting mysql

I have this SQL code which inserts into a database named daily. I regularly update the daily database like this:
INSERT INTO daily
(SELECT * FROM dailytemp
WHERE trim(`Point`) <>''
AND trim(`Point`) IN (Select trim(`Point`) FROM `data`));
I believe I am getting the error because both tables have id primary columns.
I want the data inserted, but a new id generated for any duplicate found.
I tried to list the columns names, but it's about 20 columns, which might make the process cumbersome.
What is my best option?
Edit
The table defination of daily and daily_temp are the same, all the folumns are varchar(100) with and id of (bigint)
id bigint
col1 varchar(100)
col2 varchar(100)
col3 varchar(100)
etc..
A possible solution might be to use a BEFORE INSERT trigger and a separate table for sequencing (if you don't mind).
Sequence table
CREATE TABLE daily_seq(id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY);
Now the trigger
DELIMITER $$
CREATE TRIGGER tg_daily_insert
BEFORE INSERT ON daily
FOR EACH ROW
BEGIN
INSERT INTO daily_seq VALUES(NULL);
SET NEW.id = LAST_INSERT_ID();
END$$
DELIMITER ;
Now you can insert whatever you want to daily, id value will replaced with unique auto incremented one.
Here is SQLFiddle demo
Indeed, you are certainly trying to insert a row with an id that already exists in daily.
If this does not pose any referential integrity issue, you could regenerate the id's in dailytemp so that they do not overlap with any one in daily. This might do the trick:
SET #offset = (SELECT MAX(id) FROM daily) - (SELECT MIN(id) FROM dalytemp) +1;
UPDATE dailytemp SET id = id + #offset;
Then try your INSERT.
If rows can be inserted into daily by another process than the one you described, or if for any reason a id is skipped in this table (eg. if the column is AUTO_INCREMENT), then the problem will reoccur. You may want to include this preliminary UPDATE in your daily procedure.
i decided to use a stored proceedure to perform the action, listing all colums name instead of this headache
thanks to all those who helped. Another reason i did that was that i needed to insert a date for the daily table for each set of data inserted, so i created a date column for the dail table only
INSERT INTO daily (col1, col2, etc..., created)
SELECT col1, col2, etc..., 'mydate' from daily_temp WHERE
trim(`Point`) <>'' AND trim(`Point`) IN
(Select trim(`Point`) FROM `data`));
thanks all

SQL INSERT INTO for specific cell

I'm trying to use this to insert the value "yes" into the list_title column where stream_number='3'. I can't figure out why it won't actually insert "yes" into the cell or any cell at all for that.
mysqli_query($con,"INSERT INTO livestreams (list_title) VALUE ('yes') WHERE stream_number='3'");
Heres the SQL i'm using to create the table if this helps
$createTable = "CREATE TABLE livestreams (stream_number INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(stream_number), stream_name CHAR(30), desired_username CHAR(30), stream_status CHAR(10), channel_description VARCHAR(300), game_name VARCHAR(100), viewer_count INT, list_title CHAR(30))";
What you're looking for is an UPDATE, not an INSERT. An INSERT adds new rows, while UPDATE changes something within existing rows.
UPDATE livestreams SET list_title = 'yes' WHERE stream_number = '3'
That SQL query should do.
INSERT inserts a new row into the table.
To update an existing row, use an UPDATE query.
Apparently you need to stop thinking in terms of Excel "cells". Databases work with rows a.k.a. records, and these records have fields. The datastore is not a 2D grid where you "insert" data into "cells"; even though it is often presented like that in the UI.
You should not use INSERT INTO with WHERE. Use UPDATE instead.

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

Categories