For example, server time is 15:00:00. I run the following query but it gives me wrong result. Here my query
SELECT
CASE
WHEN TIME(NOW()) BETWEEN '08:00:01' AND '10:00:00'
THEN 1
WHEN TIME(NOW()) BETWEEN '14:00:01' AND '08:00:00'
THEN 2
ELSE 0
END AS IdShift
What's wrong with my query ? from that case my expected result is 2. but it give me 0
In a BETWEEN clause you have to specify the lower value first, then the higher value.
So you have to change BETWEEN '14:00:01' AND '08:00:00' to BETWEEN '08:00:00' AND '14:00:01'.
When you want to span from 14:00 to the next day 08:00 you have to include the date.
You could do it like this:
SELECT
CASE
WHEN NOW() BETWEEN CONCAT(CURDATE(), ' 08:00:01') AND CONCAT(CURDATE(), ' 10:00:00')
THEN 1
WHEN NOW() BETWEEN CONCAT(CURDATE(), ' 14:00:01') AND CONCAT(CURDATE() + INTERVAL 1 DAY, ' 08:00:00')
THEN 2
ELSE 0
END AS IdShift
As mentioned in another answer, for between the lower bound is always first. I'm not a fan of between, but you need to split your conditions:
SELECT (CASE WHEN TIME(NOW()) BETWEEN '08:00:01' AND '10:00:00'
THEN 1
WHEN TIME(NOW()) BETWEEN '14:00:01' AND '23:59:59'
THEN 2
WHEN TIME(NOW()) BETWEEN '00:00:00' AND '08:00:00'
THEN 2
ELSE 0
END) AS IdShift
Or, phrase this with or:
SELECT (CASE WHEN TIME(NOW()) > '08:00:00' AND TIME(NOW()) <= '10:00:00'
THEN 1
WHEN TIME(NOW()) > '14:00:00' OR TIME(NOW()) < '08:00:00'
THEN 2
ELSE 0
END) AS IdShift
I would be inclined to shift the logic by a minute or two and use hours:
(case when hour(now()) >= 8 and hour(now()) < 10
then 1
when hour(now()) >= 14 or hour(now()) < 8
then 2
end)
Related
I'm having trouble writing this query to give me any results. I'm using MariaDB as well.
SELECT CallDate AS Week_Of, AgentName,
COUNT(*) AS TOTAL_Calls,
SUM(case when Accepted = 'ANSWERED' then 1 ELSE 0 END) AS Answered,
SUM(case when Accepted = 'NO ANSWER' then 1 ELSE 0 end) AS NoAnswer
FROM jshou_custom.afterhours
WHERE CallDate >= DATE_ADD(NOW(), INTERVAL -1 WEEK)
AND TIME(CallDate) BETWEEN '17:00:00' AND '08:00:00'
GROUP BY AgentName
The DATE_ADD clause works just fine and gives results within that interval, but as soon as I add in the TIME function nothing is returned in the results. The CallDate format is 2021-09-21 HH:MM:SS I have tried using HOUR as well in place of TIME, but it also returns nothing.
I'm trying to pull calls from any day within the range specified in the DATE_ADD clause. As long as it's between 1700 and 0800 (after hours calls).
I think you need to check both dates something like this and adjust the times used on each date as well
WHERE
(CallDate > DATE_ADD(CURDATE(), INTERVAL -7 DAY) AND TIME(CallDate) > '17:00:00')
OR
(CallDate > DATE_ADD(CURDATE(), INTERVAL -6 DAY) AND TIME(CallDate) < '08:00:00')
i want to count how many values of 1 and 0 i have between 7am and 7am next day.
think here a bar that opens at 10am but closes next day at 7am, they want their 'report' to be for this specific day.
so all data before 7am needs to be added to the day before.
SELECT DATE(delivered), COUNT(*) total,
sum(case when isbag = '0' THEN 1 ELSE 0 END) CloakCount,
sum(case when isbag = '1' THEN 1 ELSE 0 END) BagCount
FROM Wardrobe_CloakTable GROUP BY DATE(delivered)
this will give me almost what i want, the problem is that i need to count all those data before 7am, to the day before.
Something like this should work:
SELECT
CASE WHEN HOUR(delivered) < 7
THEN CONCAT(DATE(DATE_ADD(delivered, INTERVAL -1 day)), ' 07:00:00')
ELSE CONCAT(DATE(delivered), ' 07:00:00')
END as startTime,
CASE WHEN HOUR(delivered) < 7
THEN CONCAT(DATE(delivered), ' 07:00:00')
ELSE CONCAT(DATE(DATE_ADD(delivered, INTERVAL 1 day)), ' 07:00:00')
END as endTime,
COUNT(*) total,
sum(case when isbag = '0' THEN 1 ELSE 0 END) CloakCount,
sum(case when isbag = '1' THEN 1 ELSE 0 END) BagCount
FROM Wardrobe_CloakTable GROUP BY startTime, endTime;
SELECT COUNT(*) FROM `table` WHERE `datetime` > SUBDATE(NOW(), INTERVAL 1 DAY)
This will get number of entries during last day. But is it possible to get number of entries for multiple intervals without having to send variation of this query multiple times (INTERVAL 1 DAY, INTERVAL 1 WEEK, INTERVAL 1 MONTH, ...)?
You need CASE WHEN expression to accomplish that.
SELECT
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 1 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END) AS lastDay,
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 7 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END ) AS lastSevenDays,
COUNT(*) AS lastThirtyDays
FROM `table`
WHERE
DATE(`datetime`) >= CURDATE() - INTERVAL 30 DAY
How to use CASE WHEN expression
Note: If your requirement is to get result of last day, last 7 days and last 30 days then go with this query.
EDIT:
If you have an index on datetime field then the above query will fail to use that index. Please use the query given below in order to utilize the index on datetime.
SELECT
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 1 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END) AS lastDay,
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 7 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END ) AS lastSevenDays,
COUNT(*) AS lastThirtyDays
FROM `table`
WHERE
`datetime` >= (NOW() - INTERVAL 30 DAY - INTERVAL HOUR(NOW()) HOUR - INTERVAL MINUTE(NOW()) MINUTE - INTERVAL SECOND(NOW()) SECOND)
Can I use an alias create with the "CASE ... WHEN" (delayDate), in another function, like date_add() :
doctrine way :
->addSelect("CASE c.time
WHEN '24' then 1
WHEN '48' then 2
WHEN '72' then 3
WHEN '96' then 4
ELSE 0
END
as delayDate ,
date_add(CURRENT_DATE(), delayDate, 'DAY') as firstDateDelivery")
This because I can't use 'HOUR' in doctrine with the date_add() function.
I think, in "pure" mysql, it's not working anymore...
Can you help me please ?
F.
Remove single quote from DAY, and check this DATE_ADD() usage func_date_add.
->addSelect("CASE c.time
WHEN '24' then 1
WHEN '48' then 2
WHEN '72' then 3
WHEN '96' then 4
ELSE 0
END
as delayDate ,
CASE c.time
WHEN '24' then date_add(CURRENT_DATE(), INTERVAL 1 DAY)
WHEN '48' then date_add(CURRENT_DATE(), INTERVAL 2 DAY)
WHEN '72' then date_add(CURRENT_DATE(), INTERVAL 3 DAY)
WHEN '96' then date_add(CURRENT_DATE(), INTERVAL 4 DAY)
ELSE CURRENT_DATE()
END
as firstDateDelivery")
I've got a long MySql string that is intended to calculate a daily percentage of a certain value. However, if there is nothing for a specific day, it just skips that day and goes to the next one. I need it to spit out a "0" for the day that it usually skips. Thanks for your help!
SELECT day(timestamp), CASE when
round(count(w_comp_current_1+W_comp_current_2)*10/86400*100,1) as 'run_time2' iS NULL
then '0'
ELSE round(count(w_comp_current_1+W_comp_current_2)*10/86400*100,1) as 'run_time2' END
FROM location.db WHERE timestamp between subdate(curdate(), interval 1 month)
and curdate() AND (w_comp_current_1+w_comp_current_2) > 45
GROUP BY MONTH(Timestamp), DAY(Timestamp)
ORDER BY Timestamp
New query using calendar table:
Select date_format(calendar.timestamp,'%b-%e') as 'Month-Day', round(count(w_comp_current_1+W_comp_current_2)*10/86400*100,1) as 'run_time2' from calendar
Left Join courthouse on calendar.timestamp = courthouse.timestamp
WHERE calendar.timestamp between subdate(curdate(), interval 1 month) and curdate() and calendar.timestamp > '2013-10-03%' AND (w_comp_current_1+w_comp_current_2) > 45
GROUP BY MONTH(calendar.Timestamp), DAY(calendar.Timestamp) ORDER BY calendar.Timestamp
You have the alias for the case column twice and both times in the wrong place. It should only be given after the case's END statement:
SELECT day(TIMESTAMP), CASE
WHEN round(count(w_comp_current_1 + W_comp_current_2) * 10 / 86400 * 100, 1) IS NULL
THEN '0'
ELSE round(count(w_comp_current_1 + W_comp_current_2) * 10 / 86400 * 100, 1)
END AS 'run_time2'
FROM location.db
WHERE TIMESTAMP BETWEEN subdate(curdate(), interval 1 month) AND curdate()
AND (w_comp_current_1 + w_comp_current_2) > 45
GROUP BY MONTH(TIMESTAMP), DAY(TIMESTAMP)
ORDER BY TIMESTAMP