SQL Query to select Between two days of the month - php

I want to have a SQL Query that selects between two dates of months.
Lets say between the 15th and the 15th of the next month.
This is for accounting purposes
I know with each month having different days adding 30 days or 31 days to the start date will not work especially in Feb. My accounting run is from the 15th of the month to the 15th of the next month.
My current query for selected dates are as follows
SELECT * FROM lbs_trace_etrack WHERE lbs_date >= '" . $dates . "'
AND lbs_date <= '" . $datee . "' AND lbs_client='$slcustom1' ORDER BY lbs_date DESC, lbs_time DESC
lbs_date start should be the 15th of each month and lbs_date end should be the 15th of the next month
By defining the dates as follow works but it is giving me from the November date to now and I want it from the 15th of this month seeing we have past the 15th of the current month already
$first = date('Y-m-15', strtotime("$last -1 month"));
$last = date('Y-m-t');
and the query
SELECT * FROM lbs_trace_etrack WHERE lbs_date >= '" .
$first . "'
AND lbs_date <= '" . $last . "' ORDER BY lbs_date DESC
Basically as we pass the current month 15th I need it to show me the current usage from the current 15th not the previous month 15th to now

If you really want what I understand you want,
SELECT l.*
FROM lbs_trace_etrack l
JOIN (SELECT s.cd, CASE
WHEN s.cd >= DATE(DATE_FORMAT(s.cd,'%Y-%m-15'))
THEN DATE(DATE_FORMAT(s.cd,'%Y-%m-15'))
ELSE DATE_SUB(DATE(DATE_FORMAT(s.cd,'%Y-%m-15')), INTERVAL 1 MONTH)
AS start_date
FROM (SELECT CURDATE() cd) s) d
ON (TRUE)
WHERE l.lbs_date >= d.start_date
AND l.lbs_date < d.cd
AND l.lbs_client = '$slcustom1'
ORDER BY l.lbs_date DESC, l.lbs_time DESC;
Please note that you still have the PHP variable $slcustom1 there.
The JOIN with subselect is motivated by the need to call CURDATE() only once, to avoid the rare occasion in which the date might change between two subsequent invocations.
Please check if comparisons <, >= etc. are what you want.
Edit:
I’ve moved the computation of start_date to the joined table. Even if in this way I have to call DATE(DATE_FORMAT()) three times, it is better than to compute DATE_SUB for every row, in the case we are in the first half of the month.

Could you able to use mysql day() function for your requirement.
Ex:
SELECT day("2016.12.15");
result:
15
Like wise you can use this function to check whether its "15"
select day(currentDate())

use DAY() function to get specific date
select * from My_Table where day(str_to_date(`Date`,'%d-%m-%Y')) = 1 or day(str_to_date(`Date`,'%d-%m-%Y')) = 15;

select group_concat(year(now()),"-",month(now()),"-",15)

Related

SQL: No records in the last week

I have a table with different columns. Two of them are user and data. I want to find which users have no records in the last week.
How far have I arrived:
This gives me well the records ordered first by user and then by date:
SELECT *
FROM table1
ORDER BY user, date
I also could find a way to store one week in a var:
$oneWeek = strtotime("-1 week");
$oneWeek = date("Y-m-d H:i:s", $oneWeek);
echo $oneWeek . "<br>";
Is there a way I can select the users that do not have any records in the last seven days?
Use GROUP BY and HAVING:
SELECT t1.user
FROM table1 t1
GROUP BY t1.user
HAVING MAX(t1.date) < DATE_ADD(CURDATE(), INTERVAL -7 DAY);
This returns users whose maximum date is more than a week in the past. That is another way of saying that there are no records in the past week.

Convert integer to date in mysql ,php

I have 2 columns one having month and another year , I want to get all the records greater than that month and year
I cannot use date functions as those columns are of integer type, It gives incorrect results
How can I get records greater than that month and year
For example How can I get events which took place after february 2017
What about this approach:
SELECT * FROM table WHERE CONCAT(year, month) > 201702
WHERE CONCAT(year, month) > 201702
probably you have also some php code inside so:
$date = strtotime('2018-01-01 01:01:01');
$sql = 'SELECT * FROM YOUR_TABLE
WHERE CONCAT(year, month) > ' . date('Ym', $date);
SELECT * FROM events WHERE CONCAT(year,month) >= 201702
or without CONCAT
SELECT * FROM events WHERE( month > 2 AND year =2017) OR (year > 2017)

MySQLi "CURRENT_MONTH_BEGINNING"... is there a way to get that?

I am interested in collecting data from the last month in the database with MySQLi.
But using INTERVAL 1 MONTH each month overlaps the other, so is there a way to tell the function to check my current month, start from the first day, and collect all data from said month?
Something like:
SELECT count(DISTINCT ip) AS visitor_ip FROM visitor_list
WHERE visited_date > ( INTERVAL CURRENT_MONTH_BEGINNING)
You can just use the current year and month, and 01 as the day:
SELECT count(DISTINCT ip) AS visitor_ip
FROM visitor_list
WHERE visited_date > CONCAT(DATE_FORMAT(NOW(),'%Y%m'), '01')
This has the advantage that any index on visited_date will still be used correctly.
First you need to generate current month starting date from PHP like this:
$monthStartDate = date('Y-m').'-01';
Then your query will become:
$sql = "SELECT count(DISTINCT ip) AS visitor_ip FROM visitor_list WHERE visited_date > DATE_SUB(now(), interval (datediff(now(), '".$monthStartDate."')) day)";

Working out the amount of free dates in a given time period

I have a fun one for you. I have a database with the date columns free_from and free_until. What I need to find is the amount of days between now and 1 month today which are free. For example, if the current date was 2013/01/15 and the columns were as follows:
free_from | free_until
2013/01/12| 2013/01/17
2013/01/22| 2013/01/26
2013/01/29| 2013/02/04
2013/02/09| 2013/02/11
2013/02/14| 2013/02/17
2013/02/19| 2013/02/30
The answer would be 16
as 2 + 4 + 6 + 2 + 2 + 0 = 16
The first row only starts counting at the 15th rather than the 12th
since the 15th is the current date.
The last row is discounted because none of the dates are within a
month of the current date.
The dates must be counted as it the free_from date is inclusive and
the free_until date is exclusive.
I'm assuming DATEDIFF() will be used somewhere along the line, but I can't, for the life of me, work this one out.
Thanks for your time!
Edit: This is going into PHP mysql_query so that might restrict you a little concerning what you can do with MYSQL.
SET #today = "2013-01-15";
SET #nextm = DATE_ADD(#today, INTERVAL 1 month);
SET #lastd = DATE_ADD(#nextm, INTERVAL 1 day);
SELECT
DATEDIFF(
IF(#lastd> free_until, free_until, #lastd),
IF(#today > free_from, #today, free_from)
)
FROM `test`
WHERE free_until >= #today AND free_from < #nextm
That should work. At least for your test data. But what day is 2013/02/30? :-)
Dont forget to change #today = CURDATE();
The best I can think of is something like:
WHERE free_until > CURDATE()
AND free_from < CURDATE() + INTERVAL '1' MONTH
That will get rid of any unnecessary rows. Then on the first row do in PHP:
date_diff(date(), free_until)
On the last row, do:
date_diff(free_from, strtotime(date("Y-m-d", strtotime($todayDate)) . "+1 month"))
Then on intermediate dates do:
date_diff(free_from, free_until)
Something to that effect, but this seems extremely clunky and convoluted...
From the top of my mind... first do a:
SELECT a.free_from AS a_from, a.free_until AS a_until, b.free_from AS b_from
FROM availability a
INNER JOIN availability b ON b.free_from > a.free_until
ORDER BY a_from, b_from
This probably will return a set of rows where for each row interval you have next i.e. greater intervals. The results are ordered strategically. You can then wrap the results in a partial group by:
SELECT * FROM (
SELECT a.free_from AS a_from, a.free_until AS a_until, b.free_from AS b_from
FROM availability a
INNER JOIN availability b ON b.free_from > a.free_until
ORDER BY a_from, b_from
) AS NextInterval
GROUP BY a_from, b_until
In the above query, add a DATE_DIFF clause (wrap it in SUM() if necessary):
DATE_DIFF(b_until, a_from)

SQL Query Concerning Dates

I have the following relation in my schema:
Entries:
entryId(PK) auto_inc
date date
In order to count the total entries in the relation I use a query in my php like this:
$sql = mysql_query("SELECT COUNT(*) as Frequency FROM Entries WHERE date = '$date'");
My question is how can I count the number of entries for the CURRENT month..
You want a between query based on your date column.
WHERE date BETWEEN startdate AND enddate.
Between is equivalent to date >= startdate AND date <= enddate. It would of course be also possible to just use >= AND < explicitly which would simplify it a bit because you don't need to find the last day of the month, but just the first day of the following month using only DATE_ADD(..., INTERVAL 1 MONTH).
However startdate and enddate in this case would be derived from CURDATE().
You can use CURDATE(), MONTH(), DATE_ADD and STR_TO_DATE to derive the dates you need (1st day of current month, last day of current month). This article solves a similar problem and all the techniques needed are shown in examples that you should be able to adapt:
http://www.gizmola.com/blog/archives/107-Calculate-a-persons-age-in-a-MySQL-query.html
The first day of the current month is obvious YEAR-MONTH(CURDATE())-01. The last day you can calculate by using DATE_ADD to add 1 Month to the first day of the current month, then DATE_ADD -1 Days.
update-
Ok, I went and formulated the full query. Don't think str_to_date is really needed to get the index efficiency but didn't actually check.
SELECT count(*)
FROM entries
WHERE `date` BETWEEN
CONCAT(YEAR(CURDATE()), '-', MONTH(CURDATE()), '-', '01')
AND
DATE_ADD(DATE_ADD(CONCAT(YEAR(CURDATE()), '-', MONTH(CURDATE()), '-', '01'), INTERVAL 1 MONTH), INTERVAL -1 DAY);
Try this
SELECT COUNT(1) AS `Frequency`
FROM `Entries`
WHERE EXTRACT(YEAR_MONTH FROM `date`) = EXTRACT(YEAR_MONTH FROM CURDATE())
See EXTRACT() and CURDATE()
Edit: Changed NOW() to CURDATE() as it is more appropriate here
Try
$sql = mysql_query("SELECT COUNT(*) as Frequency FROM Entries WHERE MONTH(date) = MONTH(NOW()) );

Categories