Selecting between dates in mysql - mysql

Need to track and bill delivers based on date, for example if a deliver came in After 01/18/2010 but before 02/11/2010 it would be billed to Job no. 198.
I pretty much know it would be:
SELECT `no` FROM `jobs` WHERE 'start_date' >'2010-01-18' AND <`2010-02-11`;
in order to get '2010-01-18' AND < '2010-02-11', I have to look in the data base of course that defeats the purpose
I am given the Var=$delivery_date
And I am stuck right here.
How can I get the between dates without looking each time.
Sample of data base
no Start Date
198 2010 01 18 14:35
199 2010 02 11 12:10
200 2010 03 07 12:33
201 2010 03 31 17:35
202 2010 05 25 05:05
203 2010 06 20 01:05
204 2010 07 14 08:50
205 2010 07 21 11:31
206 2010 09 07 03:47
I hope I explained it well enough. I look at the manual and other questions but it always seems like they only have one date that is a variable and all of mine are
PS changing the format or method of the tables is not an option unless you can point me towards the time travel section

You can use the following select statement:
SELECT * FROM jobs WHERE date(start_date) BETWEEN "2010-02-08" AND "2010-03-15";
so you only take the date portion into account, not the time.
so with your date format it would be something like
SELECT * FROM jobs WHERE date(STR_TO_DATE(start_date, '%Y %m %d %h:%i')) BETWEEN "2010-02-08" AND "2010-03-15"

Looks like you want to find a jobs record with the largest start_date that's also less than $delivery_date. Here's the query
SELECT no
FROM jobs
WHERE `start_date` < $delivery_date
ORDER BY `start_date` DESC LIMIT 1
If $delivery_date is set to 2010-02-08, the above query will return 198 like you expected.
If $delivery_date is set to 2010-03-15, the above query will return 200.

thanks to ekad this worked perfectly
SELECT no
FROM jobs
WHERE start_date < $delivery_date
ORDER BY start_date DESC LIMIT 1
after the query the job no i need is first one

Related

Find date scope from MySQL efficiently

Here is my DiscountPeriod table's structure:
id
room_id
date_from
date_last
discount
Imagine that we have discount starting 01 December 2017 and ending in in 10 December 2017.
I'm searching for date-range to see if it has discount.
So date range might be totally or partly inside some of discount periods. 3 example date-ranges for search:
From 02 December to 10 December (fully inside one of discount periods)
From 20 November to 4 December (partly inside)
From 5 December to 15 December (partly inside)
Expected for all of 3 examples above is to get discount that starts in 01 December 2017 and ends in 10 December 2017.
Currently my query takes only those results which is completely inside exact period from database.
It looks like this:
SELECT * FROM `DiscountPeriod` WHERE (`room_id`=1517) AND (`date_last` >= '2017-12-12') AND (`date_from` <= '2017-12-20');
Question is, how to fit all of 3 possible search cases into 1 query for efficient searching in MySQL database tables?
Expected result is
All of following scopes: From 02 Dec to 10 Dec, From 20 Nov to 4 Dec, From 5 Dec to 15 Dec should return back 1-10 december discount.
This looks like an overlapping range problem. If you want to return all discounts which overlap with 1-10 December 2017, then try the following query:
SELECT *
FROM DiscountPeriod
WHERE
room_id = 1517 AND
'2017-12-01' <= date_last AND '2017-12-10' >= date_from;
Here is a demo which uses your test data. All three discount ranges you suggested show up in the result set. But a range lying completely outside 1-10 December 2017 is absent, as we would expect.
Demo

Mysql SQL for "replace everything but this" where xxx

I've got a terrible database on a project and they've used a text field for dates.
So, I need to build a view that has only the year in one column. The problem is that I have dates with any standard format like:
01-01-2012
01.01.2012
01 01 2012
1/1/2012
01/2012
1/2012
2012
01.2012
Is there any way to build an SQL (MySQL) to get only those 4 year digits to build a view?
Thanks a lot for your help!
It really depends on the whole data structure, you can use REGEX or String functions.
For example, with your sample data the last 4 digits on the right are the year so using
SELECT RIGHT(fieldname, 4) FROM table
would work. If that pattern doesn't work then you've either got to use concat and start splitting them or write a REGEX statement.
If RIGHT will work then you can do an INSERT SELECT
INSERT INTO table (yearcolumn)
SELECT RIGHT(fieldname, 4) FROM table
You can use REGEXP matching, to get rows from given year. There's no way to get a capture from regular expression though.
However, if the year part is alwayst last 4 digits, use RIGHT(). Otherwise, you will need to do reformatting client-side.
This may also help. This is Oracle query for the whole current year. It can be easily converted to any SQL. It uses recursive query to build annual table. Replace SYSDATE and Oracle formats with your version of SQL formats and system date:
WITH data(r, start_date) AS
(
SELECT 1 r, TRUNC(SYSDATE, 'YEAR') start_date FROM dual -- start_date: 1/1/2013
UNION ALL
SELECT r+1, TRUNC(SYSDATE, 'YEAR')+r-1 FROM data WHERE r < 365 -- any number: end_date - start_date or get the number of days in your year your way...
)
SELECT start_date
, TO_CHAR(start_date, 'YYYY') curr_year
, TRUNC(start_date, 'IW') wk_starts
, TRUNC(start_date, 'IW') + 7 - 1/86400 wk_ends
, TO_NUMBER (TO_CHAR (start_date, 'IW')) ISO_wk#
FROM data
/
START_DATE CURR_YEAR WK_STARTS WK_ENDS ISO_WK#
-----------------------------------------------------------------------
1/1/2013 2013 12/31/2012 1/6/2013 11:59:59 PM 1
1/1/2013 2013 12/31/2012 1/6/2013 11:59:59 PM 1
...
12/28/2013 2013 12/23/2013 12/29/2013 11:59:59 PM 52
12/29/2013 2013 12/23/2013 12/29/2013 11:59:59 PM 52
12/30/2013 2013 12/30/2013 1/5/2014 11:59:59 PM 1

Sort by Time using SQL

I am using VB and MySQL. I have a field named xTime and the data type is TIME. I am trying to find a way to order it ASC or enable it to have the PM/AM in it. Right now my Data is as follows and I need the 3:20 and 5:50 to be after since those should be pm. Any ideas?
62 4 3 03:20:00
61 4 3 05:50:00
56 1 1 07:40:00
Here is my SQL Statement:
SELECT ReserveID, MembershipID, Player_Count, `Time`, CourseID, `Date`
FROM reserve
WHERE (CourseID = 1) AND (`Date` = CURDATE())
ORDER BY `Time`
Actually, your code and your data seem to be fine. Your code is ordering by time ascendingly and your results are displaying it the way they should. The issue is that you're interpreting the data in the wrong way:
I need the 3:20 and 5:50 to be after since those should be pm
3:20 and 5:50 must be before 7:40 always, because those are all AM times. 3:20 PM is equal to 15:20 and 5:50 PM is equal to 17:40.

MySql Query- Date Range within a Date Range

I use mySql 5 and IIS.
I have products, that have a start date field and an end date field.
I need to run a query that will take user entered Start and End dates, and output the number of days that the product ran within the date range.
Example:
Offer1 - July 1 2011 thru July 31 2011
Query - July 1 2011 thru Sept 15 2011
Results = 31
Example:
Offer1 - July 1 2011 thru July 31 2011
Query - July 1 2011 thru July 15 2011
Results = 15
If your products have a start_date and an end_date and your query has a qstart_date and a qend_date, then we want the number of days between:
GREATEST(start_date, qstart_date)
and
LEAST(end_date,qend_date)
. In MySQL I think this looks like
1 + DATEDIFF ( 'd' , GREATEST(start_date, qstart_date) , LEAST(end_date,qend_date) )
And you'll want to ignore negative numbers, replacing them with "0".

returns Zeros for Dates that dont exist MYSQL GROUP BY

SELECT AVG(data) AS data, dateReg
FROM table
GROUP BY YEAR(dateReg), MONTH(dateReg), DAY(dateReg) ORDER BY dateReg
the Above Data Returns
1.75, 21 Jan 2010
9.45, 22 Jan 2010
3.96, 23 Jan 2010
2.68, 30 Jan 2010
Its missing dates from the 24th to 29th, Can we do it so the return value is:
1.75, 21 Jan 2010
9.45, 22 Jan 2010
3.96, 23 Jan 2010
0, 24 Jan 2010
0, 25 Jan 2010
0, 26 Jan 2010
0, 27 Jan 2010
0, 28 Jan 2010
0, 28 Jan 2010
2.68, 30 Jan 2010
You typically achieve this type of things by JOIN-ing with a value table, i.e. a table which contains all the values you are interested in.
Typical value tables may contain for example all the integer values between 0 and 1,000, or all dates for a given period. Often the Value tables include more values than desired, and we obtain the exact output desired by adding filters in the WHERE clause.
In this case you will require such a table which contain dates. Assuming this table is named ValTableDates and that it contains all the dates between January 2005 and December 2010, the query would look like:
SELECT AVG(data) AS data, VT.ValDate
FROM ValTableDates VT
LEFT JOIN table T ON T.dateReg = VT.ValDate
WHERE VT.ValDate > [Some Start Date] and VT < [Some End Date]
GROUP BY YEAR(dateReg), MONTH(dateReg), DAY(dateReg)
ORDER BY dateReg
The above query may require a bit of tweaking to get a value Zero rather than NULL, but the main point is that the Value Table is typically the simplest way to provide output records for missing data points.
An alternative is to use a function/expression that produces the desired [date] sequence, inside a subquery, but this is generally less efficient and more error prone.