IF condition within WHERE - mysql

I need to know how to use an IF condition within a WHERE clause, I leave the idea in php:
SELECT * FROM table WHERE date >= '2017-08-04'
IF(date = '2017-08-04' ){
AND hour > '12:00'
}
so the idea is that if date equals today's date then add AND hour > '12:00'

Just use basic boolean logic. The exact translation (ignoring NULL values) looks like:
WHERE date >= '2017-08-04' AND
(date <> '2017-08-04' OR hour > '12:00')
A more sensible alternative:
WHERE date > '2017-08-04' OR
(date = '2017-08-04' AND hour > '12:00')

select * from table WHERE date >= '2017-08-04'
AND hour > '12:00'

Related

How to test if there are overlapping periods with a particular period?

In my table there are two columns of type date and two columns of type time :
Here are some records of the table :
Now , in my web app I want to insert a new row in that table :
When submitting the form I want to count the number of rows where the entered period overlaps to others that are already in the database table ; by period I mean a ( beginning_date , beginning_time ) and a ( ending_date , ending_time ) together , for example ( 2016-03-15 , 12:00:00 ) and ( 2016-03-17 , 10:00:00 ).
I tried this query but it does not give the right results :
select count(identifiant) from reservation_table where ( (date_debut <= '2016-03-14' and heure_debut <= '01:00:00') and (date_fin <= '2016-03-14' and heure_fin <= '03:00:00') and (date_fin > '2016-03-14' and heure_fin > '01:00:00') ) or
( (date_debut >= '2016-03-14' and heure_debut >= '01:00:00') and (date_fin >= '2016-03-14' and heure_fin >= '03:00:00') and (date_debut < '2016-03-14' and heure_debut < '03:00:00') ) or
( (date_debut >= '2016-03-14' and heure_debut >= '01:00:00') and (date_fin <= '2016-03-14' and heure_fin <= '03:00:00') ) or
( (date_debut <= '2016-03-14' and heure_debut <= '01:00:00') and (date_fin >= '2016-03-14' and heure_fin >= '03:00:00') );
To have a better understanding about the period overlapping here is an image :
So in this image the red period is the period entered from the web app , and the black periods are those already in the database. So how to get all periods that overlap to a particular period ?
The way to test if two elements overlap is to check if the one starts before the second ends, while the second starts before the first ends, as mentioned in the overlap tag wiki.
I don't have much experience with MySql but did find this method to create a datetime value from date and time:
STR_TO_DATE(CONCAT(date, ' ', time), '%Y-%m-%d %H:%i:%s')
Once you have datetime values you can do this:
select count(identifiant)
from reservation_table
where #YourStartDatetime <= STR_TO_DATE(CONCAT(date_fin,' ', heure_fin), '%Y-%m-%d %H:%i:%s')
and #YourEndDateTime >= STR_TO_DATE(CONCAT(date_debut ,' ', heure_debut), '%Y-%m-%d %H:%i:%s')
if the count returns 0, then you have no records overlapping the period specified by #YourStartDatetime and #YourEndDateTime

mysql to check room is exists for a particular date with time duration

I have check room is exists between two time for particular date.
I have try following two query its run some time rights but, when i select 10:00 AM to 12:00 PM at time wrong results means not return any records.
QUERY-1 :
SELECT 1 FROM `timetable_details` WHERE (
((`td_from` <= '10:00:00') AND (`td_to` > '10:00:00'))
OR
((`td_from` < '12:20:00') AND (`td_to` >= '12:20:00'))
) AND ((`td_room`='1') AND (`td_date`='2016-01-25'))
QUERY-2 :
SELECT 1 FROM `timetable_details` WHERE (
(`td_from` > '07:00:00') AND (`td_to` < '08:00:00')
) AND ((`td_room`='1') AND (`td_date`='2016-01-25'))
I have get td_id = 4 number row but is not returns.
You can use between with OR condition for both columns as below :
SELECT 1 FROM `timetable_details` WHERE (((((`td_from` BETWEEN '10:00:00' AND '12:30:00') OR (`td_to` BETWEEN '10:00:00' AND '12:30:00')) AND ((`td_room`='1') AND (`td_date`='2016-01-25') AND (`td_status` IS NULL))) AND (`td_from` <> '12:30:00')) AND (`td_to` <> '10:00:00'))

MySql SELECT COUNT with two criterias

I'm trying to do a query that fetches data per the last hour and the two last hours. It's just a hits counter.
So I would like to get the resultset as follows:
id, page_url, last_hour_hits, two_last_hours_hits
The table is very simple:
id (autonumber)
page_url
time_stamp
I tried the query below:
SELECT
page_url,
COUNT(page_url) AS last_hour_hits
FROM stats
WHERE time_stamp > '2015-08-01 00:00:00'
GROUP BY page_url
('2015-08-01 00:00:00' is calculated for the last hour)
It works fine, but I have now idea how to add the 'two_last_hours' counter.
Thank you in advance.
With MySQL you can use the fact that boolean expression returns 1 for true and simplify the query to this:
SELECT
page_url
,sum(time_stamp > (now() - interval 1 hour)) as last_hour_hits
,sum(time_stamp > (now() - interval 2 hour)) as two_last_hours_hits
FROM stats
GROUP BY page_url;
This uses now() to get the current time and subtracts the interval as needed.
Just put your WHERE clause with two hours before ('2015-07-31 23:00:00') and a CASE WHEN to count for the last hour ('2015-08-01 00:00:00') :
SELECT
page_url,
COUNT(DISTINCT CASE WHEN time_stamp > '2015-08-01 00:00:00' THEN id ELSE NULL END) as last_hour_hits
COUNT(*) AS two_last_hours_hits
FROM stats
WHERE time_stamp > '2015-07-31 23:00:00'
GROUP BY page_url;
you can use join between two result sets- one for the one hour and the other for the two hours:
SELECT stats.page_url, last_hour_hits, last_two_hours_hits from
stats inner join (
SELECT page_url, COUNT(page_url) AS last_hour_hits
FROM stats WHERE time_stamp > '2015-08-01 00:00:00'
GROUP BY page_url ) as last_hour
on stats.page_url = last_hour.page_url
inner join (
SELECT page_url, COUNT(page_url) AS last_two_hours_hits
FROM stats WHERE time_stamp > '2015-07-31 23:00:00'
GROUP BY page_url ) as last_two_hours
on stats.page_url = last_two_hours.page_url

How to search between dates ? mysql

I have this query :
SELECT * FROM tabl1
WHERE
(
created_time BETWEEN
DATE_FORMAT(NOW() ,'%Y-%m-02')
AND
DATE_FORMAT(NOW() ,'%Y-%m-02')+INTERVAL 1 MONTH
AND
DAY(NOW()) > 1
)
OR
(
created_time BETWEEN
DATE_FORMAT(NOW() ,'%Y-%m-02')
AND
DATE_FORMAT(NOW() ,'%Y-%m-02')-INTERVAL 1 MONTH
AND
DAY(NOW()) = 1
)
this query will return the columns that created last month,
but the month start at day number 2 and end at the second day of the next month !
so it will return :
3.3.2015
2.3.2015
but it will not return
1.3.2015
How to write the query with better way ?
Always do this:
where datefield >= YourStartDate
and datefield < TheDayAfterYourEndDate
Dateformat returns strings and is for display purposes only.
I think you can write the query like that:
SELECT *
FROM tabl1
WHERE DATE >= '2015-02-02 00:00' AND DATE_2 <= '20015-03-02 23:59'

Select data between two dates exclude some days

I need to make query that selects data between two dates but exclude weekdays and some other days that are for example public holidays.
SELECT
`tblproduction`.`OperaterID`, `tblproduction`.`OperationID`,
SUM(`tblproduction`.`TotalProduced`) AS TotalProduced,
SUM(`tblproduction`.`TotalProducedOperator`) AS TotalProducedOp,
'Normal working day' AS DayType
FROM `tblproduction`
WHERE tblproduction.StartDateTime >= '2015-02-01 00:00:00' AND (tblproduction.StartDateTime <= '2015-02-28 23:59:59') AND tblproduction.OperaterID = 10
AND (DAYOFWEEK(tblproduction.StartDateTime) IN (1,7)) AND (DATE(tblproduction.StartDateTime) NOT IN (SELECT HolidayDate FROM tblholidays))
GROUP BY `tblproduction`.`OperaterID`, `tblproduction`.`OperationID`
UNION ALL
SELECT
`tblproduction`.`OperaterID`, `tblproduction`.`OperationID`,
SUM(`tblproduction`.`TotalProduced`) AS TotalProduced,
SUM(`tblproduction`.`TotalProducedOperator`) AS TotalProducedOp,
'Weekend' AS DayType
FROM `tblproduction`
WHERE tblproduction.StartDateTime >= '2015-02-01 00:00:00' AND (tblproduction.StartDateTime <= '2015-02-28 23:59:59') AND tblproduction.OperaterID = 10
AND (DAYOFWEEK(tblproduction.StartDateTime) NOT IN (1,7)) AND (DATE(tblproduction.StartDateTime) NOT IN (SELECT HolidayDate FROM tblholidays))
GROUP BY `tblproduction`.`OperaterID`, `tblproduction`.`OperationID`
For that purpose i have table with predefined dates that represents public holidays named tblHolidays. One of criteria in sql query is avoid counting pieces made during the holiday date. By running this query is steel includes those dates that are holidays. What should I change in query?
Maybe start with this...
SELECT p.OperaterID
, p.OperationID
, SUM(p.TotalProduced) TotalProduced
, SUM(p.TotalProducedOperator) TotalProducedOp
, CASE WHEN DAYOFWEEK(p.startdatetime) IN (1,7) THEN 'Normal working day' ELSE 'Weekend' END DayType
FROM tblproduction p
WHERE p.StartDateTime >= '2015-02-01 00:00:00' AND p.StartDateTime <= '2015-02-28 23:59:59'
AND p.OperaterID = 10
AND DATE(p.StartDateTime) NOT IN (SELECT HolidayDate FROM tblholidays)
GROUP
BY p.OperaterID
, p.OperationID
, CASE WHEN DAYOFWEEK(p.startdatetime) IN (1,7) THEN 'Normal working day' ELSE 'Weekend' END