MySQL Update activity when selecting user details - php

Table:
userid, sessionid, last_active
I got the following requests:
SELECT `userid` FROM `session_keys` WHERE `sessionid`='SESSION_ID'
UPDATE `session_keys` SET `last_active`=now() WHERE `sessionid`='SESSION_ID'
Is it possible to put it in one request? but I need the callback from the select request.
The only goal i wanna reach is to update the last_active time of an timestamp when selecting the data.
Thank you.

try:
SET #session_id = 'SESSION_ID';
SELECT `userid` INTO #sid FROM `session_keys` WHERE `sessionid` = #session_id;
UPDATE `session_keys` SET `last_active`=now() WHERE `sessionid` = #session_id;
SELECT #sid;
Could you give more context?

Try this query.
UPDATE
'tableA' AS 'A',
(
SELECT
*
FROM
'tableB'
WHERE
'id' = x
) AS 'src'
SET
'A'.'col1' = 'src'.'col1'
WHERE
'A'.'id' = x
;

Maybe this will be helpful:
Select and Update in same query (I know that you have the same table in both queries)
mysql select and update using one query in this case?

Related

Trigger not updating

I have a trigger that looks like this:
CREATE TRIGGER findavg after INSERT
ON rating
FOR EACH row
UPDATE `profile`
SET userscore = (SELECT Avg(rscore)
FROM rating
WHERE `profile`.`pid` = rating.raterid)
WHERE pid = new.pid;
where
PROFILE table - pID, name, userScore
RATING table - raterID, rScore, rDescription
It works at the first time I implemented this trigger, however yesterday I dropped all the data in both Profile and Rating table. Thus, I inserted a "freshly new" data for profile and rating.
Now everytime I insert a "RATING", the trigger won't update the userScore.
So right now, I have some PROFILE that have "0" in userScore, even though in RATING table the value is "6" for the rScore.
I'm confused because I'm pretty sure based on syntax, it's correct already.
Help me please. Thank you.
Try:
DELIMITER //
CREATE TRIGGER `findavg` AFTER INSERT ON `rating`
FOR EACH ROW
BEGIN
UPDATE `profile`
SET `userscore` = (SELECT AVG(`rscore`)
FROM `rating`
WHERE `raterid` = `pid`)
-- WHERE `pid` = NEW.`pid`;
WHERE `pid` = NEW.`raterid`;
END//
DELIMITER ;
SQL Fiddle demo

insert query only if mysql enum value is set to 'Yes'

i amn trying to run an insert query to insert the NOW() time and date only if certian enum values in my table are set to yes.
my table has 4 columns 'form1_completed', 'form2_completed', 'form3_completed', 'form4_completed'
the columns will be yes or no.
i am using this query to try and insert the current time and date into the database, its inserting but it doesnt pay attention to the where clause and just inserts anyway, can someone please show me what im doing wrong
$query2 = "IF (SELECT * FROM `supplier_session` WHERE `form1_completed` = 'Yes' AND `form2_completed` = 'Yes' AND `form3_completed` = 'Yes' AND `form4_completed` = 'Yes') INSERT INTO `supplier_session` (`completed_date`) VALUES (NOW());
WHERE `user_IP` = '$ipaddress '";
Instead of
WHERE `form1_completed` = Yes
use
WHERE `form1_completed` = 'Yes'
I think it should be:
IF EXISTS (SELECT * FROM ...) INSERT INTO ...
EXISTS (subquery) is true when the subquery returns any rows.
Or you could do:
IF (SELECT COUNT(*) FROM ...) INSERT INTO ...

determine if mysql values are in same row

How would this be done? I would like to search the database row by row. I might even print out the entire list of the database row by row. But I would also like to show record 1400 for example and determine the info on that row - such as name, gender and country.
Is it possible to use the rownum function to get this done? Or would I need to use a where in the query? But even so how would I determine the row number? Thanks.
Make one column as ID, make it PK and auto_increment. Then your query shell be something like this for #1400 row:
$pdo
->prepare(
"SELECT `name`, `gender`, `country`
FROM `foo_table` WHERE `id` = :id"
)
->execute([':id' => 1400]);
You can use user defined variables to get your rownumber in MySQL
set #nr = 0;
Now you can use this variable (same connection!) in your query
SELECT
#nr := (#nr + 1) rownumber,
*
FROM
table
see: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
do your select and add
LIMIT n,1
this will skip to n-th element(1400) and show just one result

MySQL update from select and further select and updates

Currently trying to find a way to do the following inside some form of loop (preferably without a performance hit on database).
I have 3 tables user_hours, user_calendar and hours_statistics. I need to first do:
SELECT user_calendar.date_start,
user_calendar.opportunity_id,
user_hours.user_id,
user_hours.agreed_hours,
user_hours.completed_hours,
user_hours.hours_committed
FROM user_calendar
JOIN user_hours
ON user_calendar.user_calendar_id = user_hours.user_calendar_id
WHERE user_calendar.date_start = CURRENT_DATE()
AND user_hours.completed_hours IS NULL
AND user_hours.hours_committed = 'accepted'
This query could return like the following:
http://i.imgur.com/5cJ5v.png
So for each opportunity_id and user_id returned i'd like to then do:
UPDATE user_hours
SET completed_hours = agreed_hours,
hours_committed = 'completed'
WHERE opportunity_id = {opportunity_id}
AND user_id = {user_id}
AND hours_committed = 'accepted'
AND completed_hours IS NULL
Note that {opportunity_id} and {user_id} would need to be looped at this point (see screenshot) because we need to go through each user on each opportunity.
Then for each updated record i'd need to then get the total hours like:
// Get hours they have done to send to statistics data table
SELECT sum(completed_hours) FROM user_hours WHERE user_id = {user_id} AND opportunity_id = {opportunity_id} 
// Get the completed hours total somehow as a variable
$completed_hours = (from result above)
// Commit stats
UPDATE hours_statistics SET completed_hours = (completed_hours+$completed_hours)
WHERE user_id = {user_id} AND opportunity_id =  {opportunity_id} 
Could anyone help write this as a procedure or a trigger of some kind or help me in the right direction to get a starting point for looping over this stuff? Manually the querying works, just need to be looped / automatic for a stats update to run.
You can create a trigger to update hours_statistics whenever user_hours is updated (you may also want to add similar triggers for INSERT and DELETE operations, depending on your application logic).
Assuming that a UNIQUE key has been defined on hours_statistics.(user_id, opportunity_id) one can use INSERT ... ON DUPLICATE KEY UPDATE within the trigger:
CREATE TRIGGER foo AFTER UPDATE ON user_hours FOR EACH ROW
INSERT INTO hours_statistics (user_id, opportunity_id, completed_hours) VALUES
(OLD.user_id, OLD.opportunity_id, -OLD.completed_hours),
(NEW.user_id, NEW.opportunity_id, +NEW.completed_hours)
ON DUPLICATE KEY UPDATE
completed_hours = completed_hours + VALUES(completed_hours);
Then you can use a single UPDATE statement (using the multiple-table syntax to join user_hours with user_calendar) to perform all of the updates on user_hours in one go, which will cause the above trigger to update hours_statistics as desired:
UPDATE user_hours JOIN user_calendar USING (user_calendar_id, opportunity_id)
SET user_hours.completed_hours = agreed_hours,
user_hours.hours_committed = 'completed'
WHERE user_hours.hours_committed = 'accepted'
AND user_hours.completed_hours IS NULL
AND user_calendar.date_start = CURRENT_DATE();

get columns default values as they are a row of a resultset

is there a way to get default values of columns as they are a row of a resultset?
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`state` tinyint(2) NOT NULL DEFAULT '22',
`pubdate` datetime NOT NULL DEFAULT '2012-01-01 00:00:00',
for instance a table like this should return this record:
id->NULL (?)
state->22
pubdate->2012-01-01 00:00:00
in practice, when some user opens edit.php?id=44 he will get the row 44 (update mode), but if he opens edit.php?id=0 (insert mode) I want that the fields contain default values as place holders
thank you in advance
There is a DEFAULT function
SELECT DEFAULT( id ) , DEFAULT( EXAMPLE ) FROM test LIMIT 1
With above query, it seems that you need to have atleast one record in the table as it returns no records otherwise. For current timestamp, it return a timestamp formatted string of 0s.
Sure, using the information_schema database (which stores all the information about your database structure), you can do something like:
SELECT
COLUMN_NAME,
COLUMN_DEFAULT
TABLE_NAME
FROM information_schema.COLUMNS
WHERE
TABLE_NAME='your_table_name'
AND TABLE_SCHEMA='your_database_name'
If you have a limited number of columns, you can collect them into a row using a construct like:
SELECT
id.defaultval AS id_default,
state.defaultval AS state_default,
pubdate.defaultval AS pubdate_default
FROM
(SELECT TABLE_NAME, COLUMN_DEFAULT AS defaultval FROM information_schema.COLUMNS WHERE TABLE_NAME='your_table' AND TABLE_SCHEMA='your_database' AND COLUMN_NAME='id') id
JOIN (SELECT COLUMN_DEFAULT AS defaultval FROM information_schema.COLUMNS WHERE TABLE_NAME='your_table' AND TABLE_SCHEMA='your_database' AND COLUMN_NAME='state') state ON id.TABLE_NAME = state.TABLE_NAME
JOIN (SELECT COLUMN_DEFAULT AS defaultval FROM information_schema.COLUMNS WHERE TABLE_NAME='your_table' AND TABLE_SCHEMA='your_database' AND COLUMN_NAME='pubdate') pubdate ON id.TABLE_NAME = pubdate.TABLE_NAME
Use DESCRIBE http://dev.mysql.com/doc/refman/5.0/en/describe.html
DESCRIBE sometable [somefield]
Here is php example for single field:
$resource = mysql_query("DESCRIBE sometable somefield");
$schema = mysql_fetch_assoc($resource);
$default = $schema['default'];
And here is the php example for few fields:
$resource = mysql_query("DESCRIBE sometable");
while ($schema = mysql_fetch_assoc($resource)) {
$default_list[$schema['Field']] = $schema['Default'];
}
I see no use for such a behavior and find it wrong.
It is not convenient to use. Imagine I want to enter my own state value. I'd have to delete default 22 first.
Even worse with date. Instead of setting current datetime, you are going to make me edit whole date. Why?
And for the id it is just impossible.
Why can't you just check the input fields and if empty - not to insert at all, letting database set these defaults
You just overthinked it, I believe.

Categories