(MYSQL] Use an "CASE ... WHEN" alias in a date_add function - mysql

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")

Related

How to display the time result with 24 hour calculation

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)

MYSQL: Trying to count Property_IDs over a close_dt Interval

select
pd.state AS StateName,
pd.county AS `County Name`,
CASE pc.close_dt WHEN pc.close_dt >= DATE(NOW() - INTERVAL 3 MONTH)
THEN COUNT(pd.property_id)
ELSE NULL
END AS `3 MONTH`,
CASE pc.close_dt WHEN pc.close_dt >= DATE(NOW() - INTERVAL 6 MONTH)
THEN COUNT(pd.property_id)
ELSE NULL
END AS `6 MONTH`
from resnet.property_details pd
join resnet.property_closings pc
on pd.property_id = pc.Property_id
GROUP BY pd.state,pd.county
I'm trying to get the interval of 3 months from today, 6 months from today for properties that have been closed.
I want it to look like the this:
You need conditional aggregation. In MySQL, you can do this as:
select pd.state AS StateName, pd.county AS `County Name`,
SUM(pc.close_dt >= CURDATE() - INTERVAL 3 MONTH) AS `3 MONTH`,
SUM(pc.close_dt >= CURDATE() - INTERVAL 6 MONTH) AS `6 MONTH`
from resnet.property_details pd join
resnet.property_closings pc
on pd.property_id = pc.Property_id
group by pd.state, pd.county;
Notes:
Your case syntax just doesn't make sense. You either have conditions (as case when <condition> or you have constants as case <column> when <value>). But not both.
date(now()) = CURDATE().
You don't need case expressions because MySQL treats booleans as integers in a numeric context. You can just "sum them up" to count the number of true values.
EDIT:
If you want 3-6 months, then you would do:
SUM(pc.close_dt >= CURDATE() - INTERVAL 6 MONTH AND
pc.close_dt < CURDATE() - INTERVAL 3 MONTH) AS `6 MONTH`

Cakephp how to use between and mySQL date functions

I would like to set the following query in Cakephp :
-- data in current month
SELECT * FROM myTable
WHERE DATE(`created`) BETWEEN ADDDATE(LAST_DAY(DATE_SUB(CURDATE(),INTERVAL 1 MONTH)), INTERVAL 1 DAY) AND DATE_SUB(CURDATE(),INTERVAL 0 MONTH)
I tried this, in my model Test.php :
$conditions['DATE(created) BETWEEN ? AND ?'] = array('ADDDATE(LAST_DAY(DATE_SUB(CURDATE(),INTERVAL 1 MONTH)), INTERVAL 1 DAY)', 'DATE_SUB(CURDATE(),INTERVAL 0 MONTH)');
$data = $this->find('all', array($conditions))
but this does not work, because cakephp will add quotes...
Here is the sql output :
SELECT * FROM mytable WHERE DATE(`created`) BETWEEN 'ADDDATE(LAST_DAY(DATE_SUB(CURDATE(),INTERVAL 1 MONTH)), INTERVAL 1 DAY)' AND 'DATE_SUB(CURDATE(),INTERVAL 0 MONTH)';
How can I deal with mySQL date functions in cakephp ?
In your case you must put the whole query in the array, like so:
$conditions['DATE(created) BETWEEN ADDDATE(LAST_DAY(DATE_SUB(CURDATE(),INTERVAL 1 MONTH)), INTERVAL 1 DAY) AND DATE_SUB(CURDATE(),INTERVAL 0 MONTH)'];

How do I retrieve data for the previous month in SQL

I want to get data for the dates between 2015-05-01 and 2015-06-01 using SQL.
Please help me with the query.
The query I used is:
select *,count(id) as multiple_visitors
from table1
where id=123
and (date(server_time) between (CURDATE() - INTERVAL 31 DAY) AND CURDATE())
group by user_id having count(id)>1
You can do this with month() and year():
where month(server_time) = month(curdate() - interval 1 month) and
year(server_time) = year(curdate() - interval 1 month)
However, I recommend a slightly more complex expression:
where server_time >= date_sub(date_sub(curdate(), interval - day(curdate()) + 1 day), interval 1 month) and
server_time < date_sub(curdate(), interval - day(curdate()) + 1 day)
The advantage is that there are no functions on server_time, so the database engine can use an index, if appropriate.
As a note: the expression date_sub(curdate(), interval - day(curdate()) + 1 day) gets midnight on the first day of the month.
Try using "WHERE" with MONTH(date).
Like this:
SELECT * FROM Table
WHERE MONTH(date) = 1

case when query in mysql

I want to execute below query,
when date diff is greater than 1 , how to add that in when clause as diffdate is not available there.
select
CASE (
SELECT DATEDIFF('2014-11-30','2015-11-29') AS DiffDate
)
WHEN 1 THEN "1 Day"
WHEN 7 THEN "Week"
WHEN ??? THEN "Yearly"
END;
Use an else
select CASE DATEDIFF('2014-11-30','2015-11-29')
WHEN 1 THEN '1 Day'
WHEN 7 THEN '7 Days'
ELSE 'Yearly'
END;