Updating DB depending on value - mysql

I have a table of objects:
object_id -- active -- tarif_id
1 1 5
2 0 6
3 1 19
And I have a table of tarifs:
tarif_id -- expire_date
5 2014-01-01
6 2014-05-01
19 2015-12-11
Is it possible to write an SQL that will check all object's tarif_id's expire dates with the Date.NOW and if Date.Now is more, then set object's active status to 0?

try this
UPDATE tblObject
INNER JOIN tbltarifs ON tblObject.tarif_id = tbltarifs.tarif_id
SET tblObject.active = 0
WHERE DATE_FORMAT(NOW(),'%m-%d-%Y') > DATE_FORMAT(expire_date,'%m-%d-%Y')

Sure you can. You're looking for the UPDATE function.
UPDATE ObjectsTable
SET active = 0
WHERE [tarif_id] IN (
SELECT [tarif_id]
FROM TarifTable
WHERE [expiredate] < DATE.Now --or whatever you are using to get the current date
)

Related

How do I update multiple columns in a table with multiple conditions in MySQL?

Is it possible to run an update query on multiple columns with multiple conditions in MySQL?
id name value price instock pp_flag
1 xyz 23 27 1 9
2 abc 28 12 0 8
For example above is the structure of a table myTable, where I want to run a query like:
UPDATE TABLE myTable
set value = 25
where id = 1
and price = 12
where pp_flag = 8
Just wondering if I can do this in the same query in MYSQL.
Thanks
Use and in where clause:
UPDATE TABLE myTable
set value = 25
where id = 1
and price = 12 and pp_flag = 8
What I understand is that you would like to do this
UPDATE TABLE myTable set value = 25 where id = 1
and
UPDATE TABLE myTable set price = 12 where pp_flag = 8
in a single statement.
You cannot do this as these are two independent WHERE-conditions.
You can use multiple condition to update column of a table .
As per your requirement you can use below query:
UPDATE TABLE myTable set value = 25
where id = 1 or (price = 12 and pp_flag = 8);
Hope it will help you!
Yes, it is possible by using the inbuilt IF function in MySQL (https://dev.mysql.com/doc/refman/8.0/en/if.html).
Query for your example would be:
UPDATE myTable SET
value = if(id=1, 25, value),
price = if(pp_flag=8, 12, price)

SQL Select data from table when date is either specified or empty

I want to select data from my database when a particular column in a table has a specific data or it is not filled.
here is my sql code:
SELECT
bus.bus_id,
bus.seats,
entity.entityid,
entity.company_name,
entity.logo AS companylogo,
route.start_point,
route.drop_point,
route.boarding_time,
route.arrival_time,
FROM
loading_buses
INNER JOIN bus ON loading_buses.bus_id = bus.bus_id
INNER JOIN route ON loading_buses.route_id = route.route_id
INNER JOIN entity ON bus.entity = entity.entityid AND route.entity_id =
entity.entityid
WHERE
loading_buses.`current_date` ='23/1/2018' OR
loading_buses.`current_time` >= '00:00' AND
route.start_point = 'accra' AND
route.drop_point = 'kumasi'
ORDER BY
route.price ASC
And this is my output
SQL OUTPUT
1 49 1 STC assets/images/stc.png accra kumasi 1/17/2018 20:00 1/18/2018 00:00 20 9/18/2017 7/18/2017
2 15 1 STC assets/images/stc.png accra kumasi 1/17/2018 20:00 1/18/2018 00:00 20 9/18/2017 7/18/2017
3 55 1 STC assets/images/stc.png accra kumasi 1/17/2018 20:00 1/18/2018 00:00 20 9/18/2017 7/18/2017
In my database, the column current date is has certain date which must show depending on the date inserted or if no date in the column, it must show.
So in conclusion, result from the query show show only data for the specified date and null. But Query is displaying all data in the table
current_date is used as keyword to define system date in many databases. So, please make sure It is not the case here.
current_date ='23/1/2018' --- Change date value in this condition and see if it still returns all the data.
Also, comment out this condition --- loading_buses.current_time >= '00:00'
as all the rows satisfy this condition.
if you want check for null you should use is null
WHERE loading_buses.`current_date` ='23/1/2018' OR
loading_buses.`current_time` is null
Or based on your comment you can use
WHERE loading_buses.`current_date` ='23/1/2018' AND
loading_buses.`current_time` is null
You have to use () to group your OR's:
WHERE
(loading_buses.`current_date` ='2018-01-23' OR loading_buses.`current_date` is null)
AND
route.start_point = 'accra' AND
route.drop_point = 'kumasi'

Update Multiple Rows in MySQL With Similar Content

I have an event table. (I didn't create this table)
The fields are id, event_id, start_date, end_date, e_status
The only thing that is not unique is the id. The rest are the same on all rows.
How do I update the status?
I tried:
UPDATE events
SET e_status =
CASE event_id
WHEN 12830 THEN 0
END
WHERE start_date = '2016-06-24 17:30:00'
AND end_date = '2016-06-24 18:00:00'
AND event_id IN (12830)
No updates were changed.
before editing
ID Event Status
1 USA 0
2 UK 0
3 Canada 0
Your simple query would be
update event set status=1
After Editing
ID Event Status
1 USA 1
2 UK 1
3 Canada 1
and if you wants to target specific record just use where clause
update event set status=1 where id=1
If all the data is the same on all rows except for the id column, you shouldn't need any criteria in the WHERE clause. You should be able to just have this:
UPDATE events
SET e_status =
CASE event_id
WHEN 12830 THEN 0
END
And actually, you don't even need the case statement. If all data is the same except for id, then won't all rows have an event_id = 12830? You can just have ==>
UPDATE events
set e_status = 0

Using DateTime functions to check for subscriptions that fall on booking date

I have the following tables
Subscription
id startdate spaceid vehicleid buyerid
3 2014-04-23 1 1 4
4 2014-05-20 1 2 5
SubscribedDays
id mon tue wed thur fri sat sun subscriptionid
1 1 0 0 0 1 0 0 3
2 0 0 1 0 0 0 0 4
The first table defines when a subscription starts and which space the subscription belongs to.
The second table defines the days that are part of a subscription.
There is also a Booking table that hold individual bookings but its not important here.
When placing a booking I want to first check to see if there are any subscriptions that would clash with the booking, so I need to query on the above 2 tables, providing the startdate that the booking is meant for and a spaceid, and check to see if any subscriptions exist that would prevent the booking from taking place, and return true or false accordingly. Can i do this with the current table definitions?
This will show any/all conflicts given a date and particular date and space id:
SELECT
s.startdate,
d.*
FROM
subscription s
JOIN subscribeddays d ON s.id = d.subscriptionid
RIGHT JOIN (
SELECT
'2014-04-28' AS c_dt,
dayofweek('2014-04-28') AS c_dt_wk,
1 AS c_space
FROM
DUAL
) c ON c.c_space = s.spaceid
AND s.startdate <= c.c_dt
AND (
(c.c_dt_wk = 1 AND d.sun = 1)
OR (c.c_dt_wk = 2 AND d.mon = 1)
OR (c.c_dt_wk = 3 AND d.tue = 1)
OR (c.c_dt_wk = 4 AND d.wed = 1)
OR (c.c_dt_wk = 5 AND d.thur = 1)
OR (c.c_dt_wk = 6 AND d.fri = 1)
OR (c.c_dt_wk = 7 AND d.sat = 1)
)
I used:
'2014-04-28' for the date,
1 for the space id (change these to variables in sub c)
It will show any subscriptions at that space that have already started by the prompted date and which have a 1 value for the day of week of the prompted date.
There is one problem, you do not have an end date recorded. So subscriptions that may have ended will still show up as conflicts even though they don't actually present conflicts. I would add an end date to your subscriptions table and then include that one extra line of criteria to the above query to avoid subscriptions that have ended from appearing as conflicts.
SQL fiddle test is here: http://sqlfiddle.com/#!2/62fefd/9/0
Note that April 28th, 2014 is a Monday. And I used spaceid 1 (see sub c). That conflicts w/ subscription #3 because it is also at spaceid 1 and it has a value of 1 in the MON column (the 28th is a Monday).
Try changing the values in sub c to test it out.
(note that if there are no conflicts, you'll just get 1 row of nulls back)

MySQL Calculating sum over pairwise time differences of log file

i have a table in mysql to log user actions. Each row in the table corresponds to a user action, like login, logout etc.
The table looks like:
CREATE TABLE IF NOT EXISTS `user_activity_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`action_type` smallint NOT NULL,
`action_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
id user_id action_type action_created
...
22 6 1 2013-07-21 14:31:14
23 6 2 2013-07-21 14:31:16
24 8 2 2013-07-21 14:31:18
25 8 1 2013-07-21 14:45:18
26 8 0 2013-07-21 14:45:25
27 8 1 2013-07-21 14:54:54
28 8 2 2013-07-21 15:09:11
29 6 1 2013-07-21 15:09:17
30 6 2 2013-07-21 15:09:29
...
Imagine the action 1 is login and 2 is logout and that i want to find out the total time (in hours:minutes:seconds) the user with id 6 was logged in within a specific range of dates.
My first idea was to fetch all rows with either action 1 or 2 and calculate the date differences in PHP myself. This seems rather complicated and i am sure this can be done in one query with mysql, too!
What i tried was this:
SELECT TIMEDIFF(ual1.action_created, ual2.action_created) FROM user_activity_log
ual1,user_activity_log ual2 WHERE ual1.user_id = 6 AND ual2.user_id = 6 AND
ual1.action_type = 1 AND ual2.action_type = 2 AND
DATE(ual1.action_created) >= '2013-07-21' AND
DATE(ual1.action_created) <= '2013-07-21'
ORDER BY ual1.action_created
to select all login events from ual1 and all logout events from ual2 from the same user and then calculate the pairwise time difference for day 2013.7.21, which does not really work and i don't know why.
How can i calculate the total login time (sum over all time differences, date action 2 - date action 1)?
The result from the correct operation should be 2 seconds from log id pair 22,23 + 12 seconds from log id pair 29,30 = 14 seconds.
Thank you very much for your help in advance. Best regards
I think the easiest way to structure this type of query is using correlated subqueries (and, to be honest, I generally don't like correlated subqueries, but this is an exception). Your query would probably work with the right group by clause.
Here is an alternative method:
select TIMEDIFF(action_created, LogoutTS)
from (select ual.*,
(select ual2.user_activity_log
from user_activity_log ual2
where ual2.user_id = ual.user_id and
ual2.action_type = 2 and
ual2.action_created > ual.action_created
order by ual2.action_created desc
limit 1
) as LogoutTS
from user_activity_log ual
where ual.user_id = 6 and
ual.action_type = 1
) ual
To get the total, you then need to do something like sum(TIMEDIFF(action_created, LogoutTS). However, this can depend on the format of the time column. It might look something like this:
select SUM((UNIX_TIMESTAMP(LogoutTS) - UNIX_TIMESTAMP(action_created))/1000)
Or:
select sec_to_time(SUM((UNIX_TIMESTAMP(LogoutTS) - UNIX_TIMESTAMP(action_created))/1000))