Issues with SQL - SELECT between two dates - php

I got this old system that I have to do maintenance in the place I work and they asked me to add a Date Filter on the system, but the date field is not only a field, the previous developer has split it in three, just like that "year_id", "month_id", "day_id"
And now I have to do a SELECT between the two dates (between the month and year to be more specific) and I tried just like that:
select
* from `table`
where
(
(`year_id` >= 2018 and `month_id` >= 10)
or
(`year_id` <= 2019 and `month_id` <= 3)
)
When I saw the results I realized that the query is also returning the results from Jan, Feb and Mar of 2018 and it is not supposed to do that.
How can I apply those filters?

The ideal thing you should do is add a new column
select
*,STR_TO_DATE(Concat(year_id,month_id),'%Y%m') as 'YearMonth' from `table`;
This would create a new column YearMonth and then you can use your filters
select * from (
select
*,STR_TO_DATE(Concat(year_id,month_id),'%Y%m') as 'YearMonth' from `table`
) z where (YearMonth between '201810' and '201903')

It should be possible to write a query that implements a date range filtering based on input parameters and on the existing columns. For example if you want records between October 2018 and March 2019 (inclusive), you could do:
(year_id = 2018 and month_id >= 10)
or (year_id = 2019 and month_id <= 3)
However the logic need to be adapted depending on the date range. For example if you want records between October 2017 and March 2019, then you need:
(year_id = 2017 and month_id >= 10)
or year_id = 2018
or (year_id = 2019 and month_id <= 3)
You can see that this does not scale well. For the sake of simplicity, I would suggest using str_to_date() to convert your strings to date, so you can do proper date comparison:
str_to_date(concat (year_id, '-', month_id), '%Y-%m') between '2017-10-01' and '2019-03-01'
You could add a computed column to your table that prepares the date value for you:
alter table mytable add
mydate date as (str_to_date(concat (year_id, '-', month_id), '%Y-%m'))

Thank everyone that answered && added comments, I just fixed the problem.
The solution posted by GMB worked well, you just saved me <3
I did like u suggested:
$data_inicial = Controller::toDate($data_inicial, 'm/Y', 'Y-m') . '-01';
$data_final = Controller::toDate($data_final, 'm/Y', 'Y-m') . '-01';
$query->whereBetween(DB::raw("STR_TO_DATE(CONCAT(sicc_ano_id, '-', sicc_mes_id), '%Y-%m')"), [$data_inicial, $data_final]);

Related

Select rows that fall between two times

I have a field that is a a DATETIME field.
How do I select rows that fall between between 12:00 am and 8:30 am?
when I type in this query:
$query = "select * from table where TIME(changetime) between '12:00:00 and '08:30:00'";
it gives me zero hits.
The changetime field has the date like this: 2015-07-14 10:57:57
12:00:00 is 12 PM (noon), not 12 AM (midnight). You need to use
WHERE TIME(changetime) BETWEEN '00:00:00' AND '08:30:00'
1) you don't need TIME(changetime), it could probably worsen your search-time because mysql will need to apply a function instead of using index.
use just changetime.
2) where changetime between '2015-07-14 10:57:57' and '2015-07-14 12:57:57'
http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_between
3) you need to use right range - in your example END_DATE is BEFORE START_DATE. So, between will return 0 (12:00:00 > 08:30:00)
4) look at #Barmar's comment, maybe you really want entries between some time in any date, not between the datetimes

Filter Dates in sql by months - php,sql

I have a table in sql and in that table I have column with the action date by this format: 2015-08-26 05:54:39
Now I built a system in php and i want to get all the actions that was in the same month.
I try to run that:
SELECT * FROM `Expenses` WHERE DateAction between '2015-08-01 00:00:00' and '2015-09-01 00:00:00'
and its return the actions dates that was in the same month, But its can return the the action that was in 2015-09-01 00:00:00 so i understand i need to get the last day in the month and put it in the sql query.
How I do that?
Right now this is the call to the sql:
$query = mysql_query("SELECT * FROM `Expenses` WHERE `accountid` = $accountId");
Fortunately for you, there's MySQL's MONTH() command.
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_month
SELECT * FROM `Expenses` WHERE MONTH(DateAction) = 8;
//Selects all rows in the month "August"
All months are recorded numerically (1 is January, 2 is February,...... 12 is December). It will always be precise based on your database time and date settings.
If you want to customize your query further (selecting the same year and month), then you can read more about date commands here
SELECT * FROM `Expenses` WHERE Year(DateAction) = '2015' AND MONTH(DateAction) = '8';
//Selects all rows in year 2015 and month "August"
you could use YEAR() and MONTH() or as simple as:
WHERE
DateAction >= '2015-08-01 00:00:00'
and
DateAction < '2015-09-01 00:00:00'
This will not include the september date.
I think it may help you
Suppose if you want the result or records of August, you may user the query
SELECT * FROM Expenses WHERE DATE_FORMAT(DateAction,'%c')='8'

mysql search by month and year as separate fields

I want all sum of counts between these 2 month-year here month and year are 2 separate fields.
How can I do that ? Thanks for help.
SELECT *
FROM foo
JOIN
SELECT (SUM(`full_lead_count`)) AS `domainFullLeadCount`
FROM `abc`.`reports`
WHERE ((`month` >= 10)
AND (`year` >= 2013))
AND ((`month` <= 3)
AND (`year` <= 2014)) LIMIT 1 bar ON val1 = val2
WHERE id = 123;
These premises are definitely not ideal. If it is possible to change the database layout, then you should consider to use real date datatypes from MySQL. Otherwise you could use STR_TO_DATE in order to convert your two fields into a single DATETIME, which can then be handled more easily.
Think of this as a comment rather than a useful answer...
Untested and very incomplete:
The issue is that if there was a range of year such as 2012 to 2014 then not all rows would be selected with the given example.
Something like the following will correctly select all the rows in the date range required:
SELECT (SUM(`full_lead_count`)) AS `domainFullLeadCount`
FROM `abc`.`reports`
WHERE ((`year` * 100 + `month`) >= 201310)
and ((`year` * 100 + `month`) <= 201403)
And, yes it isn't nice as indexes cannot be used etc.

MySQL - Between months (rather than a timestamp)

how would I generate a MySQL query to grab a row that is between a particular month
eg grab row where month is between 01/01 (1st Jan) and 01/06 (1st June)
I'm not sure, if you want to grab all rows from Jan to June, only the rows until June 1st or all rows from Jan to May. You can use for example:
[...] WHERE `date_column` BETWEEN '2012-01-01' AND '2012-06-01'
which gives you all rows including June 1st.
Use this to get all rows from the full months of Jan to June:
[...] WHERE YEAR(`date_column`)=2012 AND MONTH(`date_column`) BETWEEN 1 AND 6
(change to BETWEEN 1 AND 5 for Jan to May)
If you generate your SQL query in PHP, you can use BETWEEN
$date = date("Y") . '-' . date("m") . '-01';
$sql = "SELECT *
FROM `table`
WHERE `date_column` BETWEEN '$date' AND '$date' + INTERVAL 1 MONTH - INTERVAL 1 DAY";
(I subtracted one day to exclude the data of the next month first day)
Or you can use EXTRACT
$month = 5;
$sql = 'SELECT *
FROM `table`
WHERE EXTRACT(MONTH FROM `date_column`) = ' . $month;
Assuming the column in mysql is the right format (date/datetime) you can simply compare (>,<) :
SELECT somecolumn
FROM sometable
WHERE datecolumn >= '2012-01-01' AND datecolumn < '2012-06-01'
Hope it helps!
You can use the month(), year() and day() functions. So your query would look like something like
SELECT * FROM table WHERE month(date_field) >= 1 AND month(date_field) <= 6 AND year(date_field) = 2011
date_field should be a date or datetime field, if it is a timestamp, you need to use the FROM_UNIXTIMESTAMP function so it would look like month(FROM_UNIXTIMESTAMP(timestamp_field))
SELECT
*
FROM
yourtable
WHERE
date BETWEEN '2012-01-01' AND '2012-06-01';

Embedded SQL request

I have a SQL Database. In here is a table called Reports and it looks like this
ID Date Year Title Links
1 2010-05-03 2010 Report 1 link1.php
2 2010-09-03 2010 Report 2 link2.php
3 2011-01-05 2011 Report 3 link3.php
What I'm trying to achieve it the this. I want to select all the reports of 2010-2011 but the ones from 2010 may only be those dating from september.
Right now, I've got a SQL statement selecting all the reports of the two years
$sql = "SELECT * FROM Reports WHERE Year = ".$db->escape($jaar1)." OR jaar = ".$db->escape($jaar2);
How can I select Report 2 (cause it dates from september 2010) and Report 3 (cause it dates from 2011)?
The easiest way as I see it, is to use the BETWEEN...AND operator.
SELECT *
FROM `Reports`
WHERE `Date` BETWEEN '2010-09-01' AND NOW()
Note the backticks. Especially important around Date, because it is a reserved word.
Assuming the Date column is of type DATE:
SELECT *
FROM `Reports`
WHERE (YEAR(`Date`) = 2010 AND MONTH(`Date`) = 9)
OR YEAR(`Date`) = 2011
general pattern
where year = 2011
or ( year = 2010 and month = 'September' )

Categories