mysql Select Row by multiple conditions - mysql

We are working on a way to select 1 row based on multiple conditions. An example will clarify this. Below is an example of our data set.
Name StartDate EndDate HoursBegin HoursEnd RowID
Test 1 11/24/2017 8/24/2018 121 1000 1382
Test 2 11/25/2018 8/24/2020 1001 2500 1383
Test 3 11/25/2020 8/24/2022 2501 4000 1384
I am looking for a query that will take a couple of conditions (Date and Hours) and decide which row the condition fits it. Consider the following 2 examples.
Simplest case: Date: 11/25/2021 and Hours 2600. This should result in the the 3rd row being selected since both conditions are satisfied with the same row.
2nd case: Date: 11/26/2018 and Hours 2600. This should result in the 3rd row to be selected again. Our logic goes something like either by hours or date. For this I could not simple do an OR in my SELECT WHERE statement because the Date condition would be satisfied by the second row and that is not the row we want to bring back.
I have been trying to figure out how to do this for a couple of days now and have a brain freeze from thinking about it. Any help would be appreciated.

For this you need to use a where clause to filter out the rows you are interested in. Connect the clauses in the where clause with AND to signify you want all of them to be true for the row in question:
where startdate < '11/25/2021' and enddate > '11/25/2021' and
hoursbegin < '2600' and hoursend > '2600'
some sql platforms have a between operator
where '11/25/2021' between startdate and enddate and
'2600' between hoursbegin and hoursend

Related

Having Problem fetching rows from mysql table between two date columns

I am having the table and i want to fetch rows based on 'rb_rm_id' column between the 2 dates 'rb_chkin' and 'chkout'. But, It gives me 0 result even if the values are present. Please help me. Thanks in Advance.
I have Tried the Following Mysql Query but, failed:
SELECT *
FROM room_booking
WHERE `rb_rm_id` = 2 AND
(`rb_chkin` >= '2019-08-05' AND `rb_chkin` <= '2019-08-06') AND
(`rb_chkout` >= '2019-08-05' AND `rb_chkout` <= '2019-08-06');
The Table image is here [1]: https://imgur.com/eQZ1I0C "Table"
Question is not clear and also your mysql table doesn't contains any value in that range. There is no check in value in your given range.
try this one
SELECT *
FROM room_booking
WHERE `rb_rm_id` = 2 AND
(`rb_chkin` <= '2019-08-05' AND `rb_chkout` >= '2019-08-06');
Your query says:
Give me any rows where rb_chkin and rb_chkout both are between 2019-08-05 and 2019-08-06 and the rb_rm_id is 2.
There is no such row in your table.
What you probably want is to detect whether a room is booked during the given date range. For a room to be, at least partially, occupied there can three case:
The check-in date falls within the date range.
The check-out date falls within the date range.
The check-in date is before the date range, and the check-out is after the date range.
If either one of these three conditions is met the room has a booking during the given date range. The equivalent query would be:
SELECT *
FROM room_booking
WHERE `rb_rm_id` = 2 AND
(`rb_chkin` BETWEEN '2019-08-05' AND '2019-08-06') OR
(`rb_chkout` BETWEEN '2019-08-05' AND '2019-08-06') OR
(`rb_chkin` < '2019-08-05' AND `rb_chkout` > '2019-08-06');
So this returns all rows that have a booking for the given room in the given date range.
Please consider using better column names, which would make your code actually readable. Something like: rb_room_id, rb_customer_id, rb_check_in_date, rb_check_out_date. I really don't understand this need for obfuscation.

MySQL - SUM() old entries

I've a table with lots of entries consisting of dates and a number.
For instance:
07.02.2016 - 12
06.02.2016 - 48
05.02.2015 - 24
...and so on.
Now I need to sum all of the values older than 2 months. For instance the 3rd entry (05.02.2015) will be added to the second (06.02.2016) and the second one should get the value 72 and the 3rd one should be deleted.
I'd like to know if there is some way to do this in mysql only?
Instead of writing the code for you, I'd like to merely give you some hints:
Identify which rows are older than 2 month and sum them up.
select sum(number) from table where date > curdate() + interval 2 months
or sth. similar will do.
Select the max. date of the entries that are smaller or equal to "now+2months".
Update that row with the value from step 1.
Delete the rows from step 1.
See here for details on date functions in MySQL.
This can be done in 2 statements (one for steps 1-3, one for the deletion).

Pivot with changing dates

I have a script with result set something like this:
-- #Test (temptable)
Branch_Name C_Date Percentage
Branch 1 20140107 90
Branch 1 20140108 82
Branch 2 20140107 85
Branch 2 20140108 86
I would like to pivot this data, however the C_Date is populated to get 7 days back:
WHERE (1 = 1) AND
(tTable.C_Date > CONVERT(VARCHAR(10),GETDATE() -7, 112)) AND
(tEnter.C_Date < CONVERT(VARCHAR(10),GETDATE() -1, 112)).
I've tried
Select * from #Test
pivot (avg (Percentage) for C_date in ([20140107],[20140108])) as PivotTable
and it gives me the data I want (see below),
Branch_Name 20140107 20140108
Branch 1 90 82
Branch 2 85 86
but how do I get the pivot to look at dates populated by the GETDATE? I've tried putting the GETDATE command in each [] but that obviously didn't work.
** Note, my example shows 2 days, but my query is for 7 days back, not including the day it's being run.
Any help appreciated - thank you!
Instead of trying to work with the dates, try working with "the number of days between C_Date and today".
So early on (in a subquery or CTE) you do DATEDIFF(day,C_Date,GETDATE()) as NumDays.
You can then filter your where as WHERE NumDays between 1 and 7 and your pivot as:
pivot (avg (Percentage) for NumDays in ([1],[2],[3],[4],[5],[6],[7])) as PivotTable
Now, that handles most of what you need. The one thing we can't do (in plain SQL) is to convert those column names back into dates - because any particular SQL query has to produce a result set with a fixed "shape" - the number, names and types of the columns are fixed.
But hopefully that's enough to do in SQL, and if you do need to convert back into date headings, that can be done with whatever is consuming this result set.

MYSQL: Select records based on the time intervals

I have a table which contains records with datetime column. Records will be inserted into that table for every 3/5/8(dynamic) seconds.
Need: I have to show only one record per day. Here I have one condition that is the records should be inserted between 10.00 to 11.00 AM.
So I like to use that condition in where clause and use max to get the record. But I could not.
Please advice.
Try something like below:
select * from tblName where HOUR(datetime_column) between 10 AND 11 group by DAY(datetime_column)

Correct MySQL Structure for a Time Range for Query Optimization?

I have a scenario where I want to be able to SELECT rows from a MySQL table, but exclude rows where the current time-of-day is inside a time-range.
Example:
The "quiet" period for one row is 10pm - 8:30am.
My SQL SELECT statement should not return that row if the current server time is after 10pm or before 8:30am.
Example 2: The "quiet period" is NULL and ignored.
Example 3: A new row is created with a quiet period from 9:53am to 9:55am. If the current server time is in that 2-minute window, the row is not returned by the SELECT.
My question:
What data format would you use in the database, and how would you write the query?
I have thought about a few different approaches (defining start_time as one column and duration as another, defining both in seconds... or using Date stamps... or whatever). None of them seem ideal and require a lot of calculation.
Thanks!
I would store the start and end dates as MySQL native TIME fields.
You would need to consider ranges that span midnight as two separate ranges but you would be able to query the table like this, To find all current quiet periods
SELECT DISTINCT name FROM `quiet_periods`
WHERE start_time<=CURTIME() AND CURTIME()<=end_time
Or to find all non-active quiet periods
SELECT name FROM quiet_periods WHERE name NOT IN (
SELECT name FROM `quiet_periods`
WHERE start_time<=CURTIME() AND CURTIME()<=end_time
)
So with sample data
id -- name -- start_time -- end_time
1 -- late_night -- 00:00:00 -- 08:30:00
2 -- late_night -- 22:00:00 -- 23:59:59
3 -- null_period -- NULL -- NULL
4 -- nearly_10am -- 09:53:00 -- 09:55:00
At 11pm this would return
null_period
nearly_10am
from the second query.
Depending on performance and how many rows you had you might want to refactor the second query into a JOIN and probably add the relevant INDEXes too.