Here is the schema:
CREATE TABLE `available_timings` (
`id` bigint(20) NOT NULL ,
`from_time` time DEFAULT NULL,
`to_time` time DEFAULT NULL
);
INSERT INTO `available_timings` (`id`, `from_time`, `to_time`) VALUES
(1, '15:11:00' , '17:15:00'),
(2, '15:11:00', '15:11:00'),
(3, '09:00:00', '12:30:00'),
(4, '15:40:00', '15:40:00'),
(5,'13:30:00', '17:15:00'),
(6, '16:10:00', '16:10:00'),
(7, '07:45:00', '11:45:00'),
(8, '19:00:00', '22:30:00'),
(9, '16:14:00', '16:14:00'),
(10, '09:30:00', '17:45:00'),
(11, '10:30:00','15:15:00');
http://sqlfiddle.com/#!9/fc9afe/2
I am trying to achieve whether the current time falls between from time and to time in mysql
SELECT *
FROM `available_timings`
WHERE curtime() >=`from_time` or curtime() <=`to_time`
i have searched many forum and also tried few queries but couldn't succeeded.
Can any one help me here to solve my problem
Thank you
Use BETWEEN
SELECT *
FROM `available_timings`
WHERE curtime() BETWEEN `from_time` AND `to_time`
Use AND instead of OR
WHERE curtime() >= `from_time`
AND curtime() <= `to_time`
You don't want any of these conditions to be true. You want both of them to be true.
Related
I have a table which has a date column, some self-reports of happiness in another column, and a flag column which indicates a gym day.
I want to get the average happiness scores on the day before, the day of, and the day after a gym session.
If you imagine this table, the averages should return day_before = 1, day_of = 2, and day_after = 3.
So the set up is like in this fiddle, although in my actual database the gym flag column is joined in from a separate table.
CREATE TABLE test
(`date` datetime, `gym` int, `happiness` int)
;
INSERT INTO test
(`date`, `gym`, `happiness`)
VALUES
('2019-01-06 00:00:00', NULL, 1),
('2019-02-06 00:00:00', 1, 2),
('2019-03-06 00:00:00', NULL, 3),
('2019-04-06 01:00:00', NULL, 1),
('2019-05-06 01:00:00', 1, 2),
('2019-06-06 01:00:00', NULL, 3),
('2019-07-06 01:00:00', NULL, 1),
('2019-08-06 01:00:00', 1, 2),
('2019-09-06 01:00:00', NULL, 3)
;
I tried using a subquery to return when the "gym" column in date - 1 = 1, and also use the results in a case which would have "day of", "day before", and "day after" strings. Then I could simply group by that column. I couldn't get this to work and I'm not even sure if that's something you can do.
Use two self-joins.
SELECT AVG(before.happiness) AS day_before, AVG(current.happiness) AS day_of, AVG(after.happiness) AS day_after
FROM test AS current
JOIN test AS before ON before.date = DATE_SUB(current.date, INTERVAL 1 DAY)
JOIN test AS after ON after.date = DATE_ADD(current.date, INTERVAL 1 DAY)
WHERE current.gym = 1
I have a database table with an auto-update column which is required to be in the TIMESTAMP format, this saves dates in the form YYYY-MM-DD HH:mm:ss for each time a row is updated.
On reading statements that date comparisons are (possibly very) processor heavy, the preferred method seems to be to use MySQL BETWEEN statement to check and return updates that have occurred in the last 24 hours.
A reference: https://stackoverflow.com/a/14104364/3536236
My SQL
I have removed some details that take up space that are outside the scope of this question, such as some columns
-- Generation Time: Oct 14, 2015 at 04:54 PM
-- Server version: 5.5.45-cll
-- PHP Version: 5.4.31
--
-- Table structure for table `check_log`
--
CREATE TABLE IF NOT EXISTS `check_log` (
`table_id` int(8) NOT NULL AUTO_INCREMENT,
`last_action` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`ip_addr` varchar(60) NOT NULL,
`submit_fail` varchar(1) NOT NULL,
PRIMARY KEY (`fail_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=14 ;
--
-- Dumping data for table `check_log`
--
INSERT INTO `check_log` (`table_id`, `last_action`, `ip_addr`, `submit_fail`) VALUES
(2, '2015-10-14 14:08:30', '92.99.252.185', 'N'),
(3, '2015-10-14 14:09:23', '92.99.252.185', 'N'),
(4, '2015-10-14 14:09:25', '92.99.252.185', 'N'),
(5, '2015-10-14 14:09:38', '92.99.252.185', 'N'),
(6, '2015-10-14 14:14:22', '92.99.252.185', 'N'),
(7, '2015-10-14 14:17:13', '92.99.252.185', 'N'),
(8, '2015-10-14 14:20:51', '92.99.252.185', 'N'),
(9, '2015-10-14 14:20:52', '92.99.252.185', 'N'),
(10, '2015-10-14 14:50:34', '92.99.252.185', 'N'),
(11, '2015-10-14 15:29:07', '92.99.252.185', 'N'),
(12, '2015-10-14 15:31:04', '92.99.252.185', 'N'),
(13, '2015-10-14 15:32:00', '92.99.252.185', 'N');
My Query
Now, my query wants to return all the rows that fit the criteria that have been updated in the last 24hours. So:
SELECT * FROM `check_log` WHERE `ip_addr` = '92.99.252.185' AND
(`last_action` BETWEEN date_sub(CURDATE() , INTERVAL -1 DAY ) AND CURDATE())
AND `submit_fail` = 'N'
I wrote the query in this shape because I wanted to explore how BETWEEN ... AND ... handled other ANDS in the same query, and hence for my own clarity I encased the BETWEEN statement in brackets ().
I have tried a range of minorly different syntaxes for this query including:
SELECT * FROM `check_login` WHERE `ip_addr` = '92.99.252.185' AND
(DATE_FORMAT(`last_action`, '%Y-%m-%d') BETWEEN date_sub(CURDATE() , INTERVAL -1 DAY ) AND CURDATE())
and pure date check:
SELECT * FROM `check_login` WHERE
`last_action` BETWEEN date_sub(CURDATE() , INTERVAL -1 DAY ) AND CURDATE()
Each time the MySQL returns Zero Rows (not an error) but zero rows found.
I have viewed and compared at least a dozen similar answers on SO about the comparison of dates and am at a bit of a loss how I'm not getting the rows returned that I'm expecting with my query.
(I am ideally wanting to use the BETWEEN form as this table will, when in use be reaching several thousands of rows. )
What can I do to make the comparison work?
How does the BETWEEN clause handle other ANDs, is it suitable to encase in brackets (for clarity)
Is there a more efficient / suitable method to compare timestamp column dates?
It appears that DATE_SUB() is subtraction so I did not need to do -1 on the INTERVAL <value> DAY section of the SQL, however, the INTERVAL does accept negative values but that would overall be a subtraction of a negative and so a +1 Day interval.
I had originally thought for some reason DATE_SUB had stood for substitution as the allowance of negative values in the value part - to me - meant that there was no need for a data addition function as well.
I wasted half a day reading up and trying to work out how this logic worked.
Stumbled across potentially a bug(?) within phpMyAdmin, although it's more likely to maybe be my misunderstanding of MySQL, so was hoping someone could shed some light on this behaviour.
Using the following schema
CREATE TABLE IF NOT EXISTS `mlfsql_test` (
`id` int(11) NOT NULL,
`frequency_length` smallint(3) DEFAULT NULL,
`frequency_units` varchar(10) DEFAULT NULL,
`next_delivery_date` date DEFAULT NULL,
`last_created_delivery_date` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
INSERT INTO `mlfsql_test`
(`id`, `frequency_length`, `frequency_units`, `next_delivery_date`, `last_created_delivery_date`) VALUES
(1, 2, 'week', '2014-06-25', NULL),
(2, 3, 'day', '2014-06-27', NULL),
(3, 1, 'week', '2014-08-08', NULL),
(4, 2, 'day', NULL, '2014-06-26');
I want to determine rows with an upcoming delivery, based on their currently set delivery date, or their last delivery date with the frequency taken into consideration.
Came up with the following query which works fine:
SELECT *, IF (next_delivery_date IS NOT NULL, next_delivery_date,
CASE frequency_units
WHEN 'day' THEN DATE_ADD(last_created_delivery_date, INTERVAL frequency_length DAY)
WHEN 'week' THEN DATE_ADD(last_created_delivery_date, INTERVAL frequency_length WEEK)
WHEN 'month' THEN DATE_ADD(last_created_delivery_date, INTERVAL frequency_length MONTH)
END)
AS next_order_due_date
FROM mlfsql_test
HAVING next_order_due_date IS NULL OR (next_order_due_date BETWEEN CURDATE() AND CURDATE() + INTERVAL 10 DAY)
With the data currently in the table, I am expecting it to return 3 rows, but phpMyAdmin states there are a total of 4 rows of results, although it only displays 3...
I've found that if I add a WHERE clause to my query such as WHERE 1, it'll return the 3 rows and also state that there is a total of 3.
Why does it give an incorrect number of returned rows without the WHERE clause? I'm assuming without one phpMyAdmin assumes that all rows will match, however only returns those that actually did, so the count is wrong? Any help would be appreciated.
Edit: phpMyAdmin Version 4.2.0
This seems to be a bug in phpMyAdmin v4.2.x. I have opened a bug ticket (see Bug #4473). I have also proposed a fix for this bug to them (see PR #1253). You can also apply this patch to fix it in v4.2.4. This is most likely to be fixed in upcoming bugfix release i.e. v4.2.5.
Edit 1: My patch was accepted and this issue is fixed in v4.2.5 (upcoming minor release).
I have a table called 'Bill' which is a table for a database for a restaurant system. Sample data is below:
Bill_Code, Date, Customer_ID, Order_Code, Total_Amount, Discount, Payable_Amount, Payment_Type, Staff_Name
'B201404012000', '2014-03-21', 'S8909608D', 'O222224', '0.00', '0.00', '0.00', 'CASH', 'Dany Lim'
'B201404012030', '2014-04-01', 'S8409608D', 'O222221', '100.00', '0.00', '100.00', 'VISA', 'Arya Stark'
'B201404012032', '2014-04-01', 'S8609608D', 'O222222', '80.00', '0.10', '72.00', 'VISA', 'Arya Stark'
'B201404012033', '2014-04-21', 'S8709608D', 'O222223', '0.00', '0.00', '0.00', 'NETS', 'Rob Targa'
'B201404012039', '2014-04-01', 'S8709655D', 'O222225', '0.00', '0.00', '0.00', 'MASTERCARD', 'Dany Lim'
'B201404012053', '2014-04-15', 'S8909608D', 'O222224', '0.00', '0.00', '0.00', 'CASH', 'Dany Lim'
'B201404012115', '2014-04-11', 'S8909608D', 'O222226', '50.00', '0.00', '50.00', 'CASH', 'Rob Targa'
I need to find which two dates with the same Customer_ID have a date interval of 30 days.
Meaning, I need to find out if any particular customer has had a lapse of 30 days between visits.
Appreciate your help. Thanks in advance.
If you need to know returning customers with date between first and last order more than 30 days try to use GROUP BY:
SELECT Customer_ID,
MIN(Date) as MinDate,
MAX(Date) as MaxDate
FROM BILL
GROUP BY Customer_ID
HAVING DATEDIFF(MAX(Date),MIN(Date))>=30
You try this way :
To convert a time string to the number of seconds, use the strftime function with the %s modifier. (A time string without a date part will be assumed to have the date 2000-01-01, but this cancels out when computing the differences.)
To compute the pause times for a specific production record, use a correlated subquery; the total aggregate is needed to cope with zero/one/multiple matching pauses.
For example :
SELECT date,
item,
sum(strftime('%s', end) - strftime('%s', begin) -
(SELECT total(strftime('%s', end) - strftime('%s', begin))
FROM pause
WHERE pause.date = production.date
AND pause.begin >= production.begin
AND pause.end <= production.end)
) AS seconds
FROM production
GROUP BY date,
item
I want to draw a graph accurately, Time vs Site Visits.
X axis will be 4, 8, 12, 16, 20, 24. That's increments of four hours.
Y axis total number of visits by first 4 hours, then by next four hours etc.
How can I do it using MySql? There might be some tricks using GROUP BY, but I couldn't get it. I stored all visit to my site, used unix time stamp for time.
The query can be like this -
SELECT FLOOR(HOUR(FROM_UNIXTIME(unix_ts)) / 4) period, COUNT(*) visit_count_per_4_hours FROM visits_table
WHERE DATE(FROM_UNIXTIME(unix_ts)) = DATE(NOW())
GROUP BY period;
This query returns visits for specified day, otherwise calculation should be modified.
TRY
SELECT SUM( visit ) , HOUR( `time_column` )
FROM time_table
WHERE DATE_SUB( `time_column` , INTERVAL 4 HOUR )
GROUP BY HOUR( `time_column` )
working example
CREATE TABLE IF NOT EXISTS `time_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`waqt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`visit` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
--
-- Dumping data for table `time_table`
--
INSERT INTO `time_table` (`id`, `waqt`, `visit`) VALUES
(1, '2011-07-28 13:29:04', 3),
(2, '2011-07-28 15:29:10', 4),
(3, '2011-07-28 13:45:35', 7),
(4, '2011-07-28 15:00:47', 5),
(5, '2011-07-28 14:45:03', 6),
(6, '2011-07-28 13:00:21', 3);
and then i execute per hour visit
SELECT SUM(visit), HOUR(waqt)
FROM time_table
WHERE DATE_SUB(`waqt`,INTERVAL 1 HOUR) GROUP BY HOUR(waqt)