Select dates between this monday and this friday - php

I have a table with a date field (2013-07-11 = July 11th, 2013).
I need to select entries from the monday (the start of my week) of any given week until the end of that week.
I've seen queries that can grab rows whose date is 1 week ago, but I specifically need to grab rows that have a date field that occurs this week, regardless of what the current day of the week is.
I'm currently grabbing it in php using this, but I feel like there has to be a mysql method for calculating the beginning and end of this week:
$this_monday = date('Y-m-d', strtotime('previous monday'));
$this_friday = date('Y-m-d',strtotime('this friday'));
$sql = "SELECT `date`, $sign FROM `horoscopes`
WHERE `date` >= '$this_monday' AND `date` <= '$this_friday'
AND type = 'Daily'
ORDER BY `date` ASC
";
And I'm pretty sure that on monday it will end up grabbing monday of last week, not monday.
from this data set I'd like to select the following:
+------------+
| date |
+------------+
| 2013-07-12 |
| 2013-07-11 |
| 2013-07-10 |
| 2013-07-09 |
| 2013-07-17 |
| 2013-07-08 |
| 2013-07-05 |
+------------+
7-8, 7-9, 7-10, 7-11, 7-12 regardless of the day of the week.

Just learned about the WEEK() function in mysql
SELECT `date` FROM horoscopes WHERE WEEK(`date`) = WEEK(NOW(), -1);

Related

Get month difference only if the days are the same

How can I get the difference of months between two dates in MySQL only if the days are the same? Here is what i have so far but it doesn't work because when the days are not the same, it still works:
TIMESTAMPDIFF(MONTH, '2019-05-05', '2019-06-05')
Output: 1
TIMESTAMPDIFF(MONTH, '2019-05-05', '2019-06-22')
Output: 1 // should NOT work because days are 05 and 22. Needs to be the same dates
I can obviously do:
DAY('2019-05-05') = DAY('2019-06-05') AND TIMESTAMPDIFF(MONTH, '2019-05-05', '2019-06-05')
but how can I do it in one function?
Thanks!
SUBDATE()/ADDDATE/DATE_SUB/DATE_ADD will handle this well:
SELECT DATE_SUB('2019-06-22', INTERVAL 1 MONTH) = '2019-05-05'
| DATE_SUB('2019-06-22', INTERVAL 1 MONTH) = '2019-05-05' |
| ------------------------------------------------------: |
| 0 |
SELECT DATE_SUB('2019-06-22', INTERVAL 1 MONTH) = '2019-05-22'
| DATE_SUB('2019-06-22', INTERVAL 1 MONTH) = '2019-05-22' |
| ------------------------------------------------------: |
| 1 |
See the DBfiddle
In MySQL, you can get it by using the below query...
select DATEDIFF('2019-06-22', '2019-05-05') as Diff from table_name where
day('2019-06-22') == day('2019-05-05');
using column name...
select DATEDIFF(dateColum2, dateColum1) as Diff from table_name where
day(dateColum2) == day(dateColum1);
From PHP you can get it like below...
$dateValue1 = '2019-05-05';
$dateValue2 = '2019-06-22';
$time1=strtotime($dateValue1);
$day1=date("D",$time1);
$time2=strtotime($dateValue2);
$day2=date("D",$time2);
if($day1 == $day2 ) {
$seconds_diff = $time2 - $time;
}

mysql select sort by day and time str_to_date

I have a mysql table as
Table: orders
Order | day | time
1 | Tuesday 31-10-2017 | 10:00 AM
2 | Thursday 02-11-2017 | 11:00 AM
3 | Tuesday 31-10-2017 | 01:00 PM
4 | Tuesday 31-10-2017 | 10:00 AM
5 | Sunday 29-10-2017 | 09:30 AM
I need to sort orders based on day and time , for example:
Order | day | time
5 | Sunday 29-10-2017 | 09:30 AM
1 | Tuesday 31-10-2017 | 10:00 AM
4 | Tuesday 31-10-2017 | 10:30 AM
3 | Tuesday 31-10-2017 | 01:00 PM
2 | Thursday 02-11-2017 | 11:00 AM
tried:
select * from request ORDER BY STR_TO_DATE(time,'%h:%i%p') asc, STR_TO_DATE(day,'%l %d-%m-%Y') desc
but thats not sorting as expected...
Really, you should store dates using internal date formats, not as a string. You can readily get the date of the week using date/time functions.
Your date format makes this even harder, but you can do:
order by str_to_date(substring_index(day, ' ', -1), '%d-%m-%Y'),
str_to_date(time,'%h:%i%p')
Now that you've fixed this problem, go back to your data and do:
alter table orders add column orderdate datetime;
update orders
set orderdate = addtime(str_to_date(substring_index(day, ' ', -1), '%d-%m-%Y'),
str_to_date(time,'%h:%i%p'));
Check that orderdate is correct. Then do:
alter table orders drop column day;
alter table orders drop column time;
Isn't that nice? Your data is now fixed.
First, you should order the more important column first. So the order of the order statements should be;
ORDER BY STR_TO_DATE(day,'%l %d-%m-%Y') desc, STR_TO_DATE(time,'%h:%i%p') asc
And the day column should be ordered asc, not desc;
ORDER BY STR_TO_DATE(day,'%l %d-%m-%Y') asc, STR_TO_DATE(time,'%h:%i%p') asc
By the way, I think the pattern of the day of the week should be %W instead of %l;
ORDER BY STR_TO_DATE(day,'%W %d-%m-%Y') asc, STR_TO_DATE(time,'%h:%i%p') asc
I tried here;
http://sqlfiddle.com/#!9/f8fdbf/11/0
Following query will work:
select * from request
ORDER BY STR_TO_DATE(SUBSTRING_INDEX(day,' ',-1),'%d-%m-%Y'),
STR_TO_DATE(time,'%h:%i%p') desc,

Splitting month into weeks and using GROUP BY

This is a question, which I could not find answer to anywhere. Okay. here it is.
I have two date ranges (This month and the last month)
Last month - 01/01/2015 (January 1 2015) to 31/01/2015
This month - 01/02/2015 (1st Feb 2015) to 28/02/2015
Now, each month has weeks. I have a table with column created_at. I want to fetch all the records week-wise into an array (to plot a graph) with their corresponding sum(value) or count(value) .
So it will be something like this:
Last Month:
Week 1 - 25
Week 2 - 34
etc.
This Month:
Week 1: 55
Week 2: 56
etc.
The date is in this format in created_at: 2015-07-21 01:27:14 (Y-m-d H:i:s)
In MySql You can use WEEK() to get the number of the week (from 1 to 53)
O you can use WEEKDAY() or DAYOFWEEK() the first bigins on Monday the second on Sunday.
You can use them into a GROUP BY with HAVING
Something like:
SELECT count(*)
FROM `YourTable`
WHERE `created_at` >= '2015-10-01' AND `created_at`< '2015-11-01'
GROUP BY WEEK(`created_at`)
To use the workaround you found You need to do something similar:
create a table named "numbers" with a field "id" (autoincrement) and 31 rows (one for each day of a month)
Then use a query like this:
SELECT count(i.created_at)
FROM
(SELECT DATE_FORMAT(DATE_ADD('2015-12-01', INTERVAL -n.id DAY), '%Y-%m-%d') AS AllDays
FROM numbers n) AS DaysOfMonth
Left Join
YourTableName i
ON STR_TO_DATE(i.created_at, '%Y-%m-%d') = DaysOfMonth.AllDays
GROUP BY WEEK(AllDays)
(try to adapt it to your needs)
What you need to do is group by the week and then sum the values. Here's a simple example of how it might work:
SELECT DATE_FORMAT(created_at,'%Y-%V') as interval, SUM(units_sold) as total_sold
FROM sales
GROUP BY DATE_FORMAT(created_at,'%Y-%V')
What you'll be getting is the year ant week number (ex. 2015-50) and the sum from that interval.
A table like this:
+----+------------+---------------------+
| id | units_sold | created_at |
+----+------------+---------------------+
| 1 | 2 | 2015-01-01 09:00:00 |
| 2 | 4 | 2015-01-04 10:00:00 |
| 3 | 1 | 2015-01-12 12:00:00 |
| 4 | 4 | 2015-01-16 13:00:00 |
+----+------------+---------------------+
Would result to:
+----------+------------+
| interval | total_sold |
+----------+------------+
| 2015-01 | 6 |
| 2015-03 | 5 |
+----------+------------+
I think it is useful for you...
SELECT GROUP_CONCAT(id), COUNT(id) AS idcount,SUM(id) AS idsum,
MONTHNAME(order_created_date) AS month_name, WEEK(order_created_date)
AS weeks FROM orders GROUP BY WEEK(order_created_date)

SQL count distinct visits of a customer with opening hours from 10am to 6am

I am writing a customer loyalty software for a club that opens from 10am to 6am everyday. The data is store in MYSQL and I'd like to count the customer's total visits for the month.
I am using count(distinct(date)) but if the player came at 5pm and stayed till 3am with 2 transactions at 10pm and 2am. It will be counted as 2 visits instead of 1.
I have a transaction table with the columns listed below:
ps: anything in the brackets () is not real data. I get about 2000 transactions a day. I am also able to change the table structure
Transaction_ID | Date(not Date/Time) | Customer_ID | Item | price | timestamp
1 | 11-06-2015 (6pm) | Jane | drink| 2.00 | 156165166
2 | 09-06-2015 (2pm) | Jane | drink| 2.00 | 1433858493
3 | 10-06-2015 (3am) | Jane | drink| 2.00 | 1433906073
4 | 06-06-2015 (6pm) | Jane | drink| 2.00 | 156165166
Current code returns {4, Jane}. The answer I'm looking for is {3,Jane}. Transaction {2,3} should be considered as one visit
SELECT count(distinct(Date)) as visit, Customer_ID
FROM transaction
GROUP BY Customer_ID
WHERE timestamp BETWEEN $timestamp1 AND $timestamp2
$timestamp1 = strtotime("first day of february +10am");
$timestamp2 = strtotime("first day of march +6am");
How do you suggest to accurately count the total visits below? I am able to change the table structure from Date to Date/time.
The easiest answer with least changes to my codes.
SELECT count(DISTINCT(DATE(DATE_SUB(from_unixtime(timestamp),INTERVAL 6 HOUR))) as visit, Customer_ID
FROM transaction
GROUP BY Customer_ID
WHERE timestamp BETWEEN $timestamp1 AND $timestamp2
The easiest way is to shift your datetime (date,timestamp?) field back for 6 hours in a SQL statement and then you will get an interval in one day from 4AM to 12PM:
DISTINCT(DATE(DATE_SUB(dt,INTERVAL 6 HOUR)))
SQLFiddle demo
Here is the code you need:
SELECT
Customer_ID 'Customer ID'
, COUNT(DISTINCT visit) as 'Visits per month'
, MONTH(visit) 'Month'
, YEAR(visit) 'Year'
FROM
(SELECT
*
, CASE
WHEN (t_timestamp > Date_StartDate AND t_timestamp < Date_EndDate)
THEN d_date
WHEN (t_timestamp < Date_StartDate)
THEN date_add(d_date, INTERVAL -1 DAY)
END 'visit'
FROM
(SELECT *
, DATE_ADD(CAST(d_date AS DATETIME), INTERVAL 10 HOUR) Date_StartDate
, DATE_ADD(DATE_ADD(cast(d_date AS DATETIME), INTERVAL 6 HOUR), INTERVAL 1 DAY) Date_EndDate
FROM transactions) Results
) Results
GROUP BY customer_id, month(visit), year(visit)
Also, here is a SQLFiddle with the results of the code.
I haven't used the exact format for your Customer_ID (I've used INTEGER instead of VARCHAR) and didn't use the exact dates you used in your example, but obviously it should work for anything.
Consider adjusting the name of the columns used in my query to the appropriate column names and you should be fine.

mysql select month from timestamp

I have a mysql query but it's not working properly yet. The idea is: I have a month calendar, so I select all items with the current month form my db.
I select TV show episodes, they air on a specific date but they are available the next day. I want to have the available dates in my cal. So a specific example: An episode aires 2013-03-31 and is available on 2013-04-01. This episode will not be selected from the db. I have tried something like this:
$this->db->where('MONTH(FROM_UNIXTIME(first_aired+86400))='.$month);
But it didn't work. Does anyone know a solution? This is my full code:
$this->db->select('*, episodes.overview as overview, episodes.id as ep_id, shows.id as id');
$this->db->from('episodes');
$this->db->join('shows', 'episodes.imdb_id = shows.imdb_id');
$this->db->where('CHAR_LENGTH(episodes.ep_title) > 1');
$this->db->where('MONTH(FROM_UNIXTIME(first_aired))='.$month);
$this->db->where('YEAR(FROM_UNIXTIME(first_aired))='.$year);
$this->db->order_by('episodes.first_aired', 'DESC');
$data = $this->db->get()->result_array();
Thanks in advance!
Use MySQLs DATE_ADD function:
select mydate, date_add(mydate, interval 1 day) from testdata;
So if you want to get the month of the next day, use month(date_add(...))
mysql> select mydate, date_add(mydate, interval 1 day) "next day", month(date_add(mydate, interval 1 day)) "month of next day" from testdata;
+------------+------------+-------------------+
| mydate | next day | month of next day |
+------------+------------+-------------------+
| 2013-01-31 | 2013-02-01 | 2 |
| 2013-01-01 | 2013-01-02 | 1 |
+------------+------------+-------------------+
2 rows in set (0.00 sec)
So for your query, use something like $this->db->where('MONTH(DATE_ADD(first_aired, INTERVAL 1 DAY))='.$month);. Oh, and you might have to add a FROM_UNIXTIME here and there.

Categories