I want to update number 2 with status = 8
UPDATE tqueue
SET status = '8'
WHERE (SELECT MIN(number)
FROM tqueue
WHERE STATUS IN ('4')
AND get_ticket >= CURDATE( )
AND get_ticket < DATE_ADD( CURDATE(), INTERVAL 1 DAY)
GROUP BY service)
Output:
--------------------------------------------------
number | status | get_ticket
--------------------------------------------------
3 4 2017-02-18 13:43:01
2 4 2017-02-18 12:34:03
1 8 2017-02-18 10:04:59
Are you looking for updating min number in status=8 into status=4 ?
Try this one:
SELECT #mynumber:=number FROM tqueue
WHERE STATUS = '4'
AND get_ticket >= CURDATE( )
AND get_ticket < DATE_ADD( CURDATE() , INTERVAL 1 DAY )
GROUP BY service
order by number asc
limit 0,1 ;
UPDATE tqueue SET status = '8' where number = #mynumber ;
Also, you can use temporary table for update self-reference:
CREATE TEMPORARY TABLE mytbl_numbers AS
SELECT number FROM tqueue
WHERE STATUS = '4'
AND get_ticket >= CURDATE( )
AND get_ticket < DATE_ADD( CURDATE() , INTERVAL 1 DAY )
GROUP BY service
order by number asc
limit 0,1 ;
UPDATE tqueue SET status = '8' where number in (SELECT * FROM mytbl_numbers) ;
More useful Answers may be found at [+] & [+] & ...
Related
I am trying to run this query against tickets table. ticket_updates table contains rows matching tickets.ticketnumber = ticket_updates.ticketnumber
I want to check for rows in tickets where the last row in ticket_updates.datetime is >= 1 hour ago.
The problem with the below is that it's picking up rows from ticket_updates where datetime is over 1 hour ago, because its in my WHERE clause, so it's completely ignoring the most recent row which in fact is only 10 minutes ago.
So I think I need to remote the datetime from my WHERE clause, but I'm not sure what to add to make it work.
SELECT * FROM tickets WHERE
(
status = 'Pending Response' AND
ticketnumber IN
(
SELECT ticketnumber FROM ticket_updates WHERE
type = 'customer_reminder_flag' AND
datetime < NOW() - INTERVAL 2 DAY
)
) OR
(
status = 'Pending Completion' AND
ticketnumber IN (
SELECT ticketnumber FROM ticket_updates WHERE
type = 'update' AND
datetime < NOW() - INTERVAL 1 HOUR
ORDER BY datetime DESC
)
)
You can re-write your query using EXISTS as follows:
SELECT t.*
FROM tickets t join ticket_updates tu on t.ticketnumber = tu.ticketnumber
WHERE t.status = 'Pending Completion'
AND tu.type = 'update'
AND tu.datetime < NOW() - INTERVAL 1 HOUR
AND NOT EXISTS
(SELECT 1 FROM ticket_updates tuu
WHERE tu.ticketnumber = tuu.ticketnumber
AND tuu.type = 'update'
AND tuu.datetime < NOW() - INTERVAL 1 HOUR
AND tuu.datetime > tu.datetime
)
If you are running on mysql 8.0+ then you can use analytical function as follows:
SELECT * FROM
(SELECT t.*, row_number() over (partition by tu.ticketnumber order by tu.datetime) as rn
FROM tickets t join ticket_updates tu on t.ticketnumber = tu.ticketnumber
WHERE t.status = 'Pending Completion'
AND tu.type = 'update'
AND tu.datetime < NOW() - INTERVAL 1 HOUR) t
WHERE RN = 1
I want to check for rows in tickets where the last row in ticket_updates.datetime is >= 1 hour ago.
For this problem statement, the code would use not exists:
select t.*
from tickets t
where not exists (select 1
from ticket_updates tu
where tu.ticketnumber = t.ticketnumber and
tu.datetime > now() - interval 1 hour
);
This returns tickets that have had more than one hour since the last update.
It is unclear to me what this problem statement has to do with the code you have shown.
Using MYSQL, I have written two big SELECT queries combined by a UNION, to get 2 rows, where the first row is the count for the current month, and the second row is the count for the previous month. The Query is as follows:
select * from
(select count(*) as type1 from table_x where nationality_id = 23 and month(START_DATE) = month(now())) as t1,
(select count(*) as type2 from table_x where nationality_id = 24 and month(START_DATE) = month(now())) as t2,
(select count(*) as type3 from table_x where nationality_id = 25 and month(START_DATE) = month(now())) as t3,
(select count(*) as type4 from table_x where nationality_id = 26 and month(START_DATE) = month(now())) as t4
UNION
select * from
(select count(*) as type1 from table_x where nationality_id = 23 and month(START_DATE) = month(now() - INTERVAL 1 MONTH)) as t1,
(select count(*) as type2 from table_x where nationality_id = 24 and month(START_DATE) = month(now() - INTERVAL 1 MONTH)) as t2,
(select count(*) as type3 from table_x where nationality_id = 25 and month(START_DATE) = month(now() - INTERVAL 1 MONTH)) as t3,
(select count(*) as type4 from table_x where nationality_id = 26 and month(START_DATE) = month(now() - INTERVAL 1 MONTH)) as t4
I want to add a third row, which is the difference between row 2 and row 1.
How can I do this with my current query?
You are obviously doing a compare between current and prior month. So, I would start with my inner pre-query aggregate getting only those transactions >= the first of the prior month AND the records within the nationality IDs you are looking for.
The inner date_sub() of DAYOFMONTH() -1 day gives you the first of the CURRENT month. By subtracting one more month, gives you the first of the LAST month.
Now you can aggregate the totals per nationality compared to current month or not. That inner query gives you all begin and end counts. Now that is wrapped to the outer and you can get all the counts in addition to the differences... Obviously you can change the column names respectively.
select
PQ.*,
PQ.ThisMonth23 - PQ.LastMonth23 = Diff23,
PQ.ThisMonth24 - PQ.LastMonth24 = Diff24,
PQ.ThisMonth25 - PQ.LastMonth25 = Diff25,
PQ.ThisMonth26 - PQ.LastMonth26 = Diff26
from
( select
sum( case when t.Nationality_id = 23 and month( t.StartDate ) = month( now()) then 1 else 0 end ) ThisMonth23,
sum( case when t.Nationality_id = 24 and month( t.StartDate ) = month( now()) then 1 else 0 end ) ThisMonth24,
sum( case when t.Nationality_id = 25 and month( t.StartDate ) = month( now()) then 1 else 0 end ) ThisMonth25,
sum( case when t.Nationality_id = 26 and month( t.StartDate ) = month( now()) then 1 else 0 end ) ThisMonth26,
sum( case when t.Nationality_id = 23 and month( t.StartDate ) != month( now()) then 1 else 0 end ) LastMonth23,
sum( case when t.Nationality_id = 24 and month( t.StartDate ) != month( now()) then 1 else 0 end ) LastMonth24,
sum( case when t.Nationality_id = 25 and month( t.StartDate ) != month( now()) then 1 else 0 end ) LastMonth25,
sum( case when t.Nationality_id = 26 and month( t.StartDate ) != month( now()) then 1 else 0 end ) LastMonth26
from
table_x t
where
t.StartDate >= date_sub( date_sub( t.StartDate, interval DAYOFMONTH( t.StartDate ) -1 DAY ), interval 1 MONTH )
AND t.Nationality_id IN ( 23, 24, 25, 26 )
) PQ
I would just add that your query might be getting more than you think... You are asking for ALL records Ex: January REGARDLESS of the year, compared to ALL records December REGARDLESS of the year because all you are qualifying is based on the MONTH() and no YEAR() consideration. I am explicitly querying back only current and prior month.
How do I get the today's deals only with deal_expiry_date_time is greater that current time?
SELECT *
FROM `deals` AS `d`
WHERE d.status = 'Active' AND d.deal_end_date_time BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 0 DAY)
AND d.created_by_id = '11'
ORDER BY `d`.`deal_id` ASC
LIMIT 5
To select everything from now to the end of the day
SELECT *
FROM `deals` AS `d`
WHERE d.status = 'Active'
AND d.deal_end_date_time BETWEEN NOW() AND CONCAT(CURDATE(), " 23:59:59")
AND d.created_by_id = '11'
ORDER BY `d`.`deal_id` ASC
LIMIT 5
To select everything from now to tomorrow
SELECT *
FROM `deals` AS `d`
WHERE d.status = 'Active'
AND d.deal_end_date_time BETWEEN NOW() AND NOW() + INTERVAL 1 DAY;
AND d.created_by_id = '11'
ORDER BY `d`.`deal_id` ASC
LIMIT 5
My suggestion is to have both datetime and date in your table to avoid loosing indexes filtering with funcs
Not sure if following sql is what you want or not, if you post some sample data and expected result, then we will understand your logic better.
SELECT *
FROM `deals` AS `d`
WHERE d.status = 'Active'
AND d.deal_end_date_time >= NOW()
AND DATE(d.deal_end_date_time) = CURRENT_DATE
AND d.created_by_id = '11'
ORDER BY `d`.`deal_id` ASC
LIMIT 5
SELECT *
FROM `deals` AS `d`
WHERE d.status = 'Active' AND CAST( d.deal_end_date_time AS date ) = CURRENT_DATE
AND d.created_by_id = '11'
ORDER BY `d`.`deal_id` ASC
LIMIT 5
I would like to pull all rows where the status column IS NOT marked 'deleted' AND where the status is marked 'completed' if the update_datetime column is older than 7 days (MySQL version 2013-04-11 11:22:44 ).
Here's my feeble and failed attempt:
WHERE
status <> 'deleted'
OR status <> 'completed'
AND update_datetime < unix_timestamp( now() - interval 7 day )
WHERE
status <> 'deleted'
AND (
(update_datetime < unix_timestamp( now() - interval 7 day ) AND status = 'completed')
OR (update_datetime >= unix_timestamp( now() - interval 7 day ))
)
If the update_datetime is a DATETIME column, use this instead:
WHERE
status <> 'deleted'
AND (
(update_datetime < DATE_SUB(NOW(), INTERVAL 7 day) AND status = 'completed')
OR (update_datetime >= DATE_SUB(NOW(), INTERVAL 7 day))
)
Do you mean this?
WHERE
(status <> 'deleted'
OR status <> 'completed')
AND update_datetime < unix_timestamp( now() - interval 7 day )
it is equal to
WHERE
(not status in ('deleted', 'completed'))
AND update_datetime < unix_timestamp( now() - interval 7 day )
I need to select all users who "fits" in theirs working timetables.
Table in MySQL
Timetable:
user_id PRIMARY
day_number(0-sunday 6-saturday) PRIMARY (one user - one day)
start start worktime
end end worktime
Sample user:
user_id = 1
day_number = 1
start = 10:00
end = 18:00
user_id = 1
day_number = 2
start = 12:00
end = 18:00
user_id = 1
day_number = 3
start = 14:00
end = 16:00
Now I want select every user who works from 1(Monday) to 3(Wednesday) from 14:00 to 16:00.
Sample user (with id 1) should be included.
Any Ideas?
SELECT user_id
FROM my_table
NATURAL JOIN (SELECT 1 day_number UNION ALL SELECT 2 UNION ALL SELECT 3) days
JOIN (SELECT MAKETIME(14,0,0) start, MAKETIME(16,0,0) end) times
ON my_table.start <= times.start
AND my_table.end >= times.end
GROUP BY user_id
HAVING COUNT(DISTINCT my_table.day_number) = 3 -- number of days in range
See it on sqlfiddle.
Try this query
SELECT *
FROM `Timetable`
WHERE day_number between
1 and 3
AND TIME_TO_SEC( start ) <= TIME_TO_SEC( '14:00' )
AND TIME_TO_SEC( end ) >= TIME_TO_SEC( '16:00' )
Or
SELECT *
FROM `Timetable`
WHERE day_number in (1,2,3 )
AND TIME_TO_SEC( start ) <= TIME_TO_SEC( '14:00' )
AND TIME_TO_SEC( end ) >= TIME_TO_SEC( '16:00' )
Try the code below:
Select * from Timetable
Where day_number>=1 and day_number <=3 And
hour(start) >= 12 and hour(end)<= 16