calculate date difference between consecutive rows in mysql - php

I have a TABLE in mysql with Columns:
id, created_time, name
Every row has id and the date time when it has been created . For example below:
id created_on name
1 2020-12-03 13:15:09 john
2 2020-11-08 14:11:19 john
3 2020-10-06 14:11:19 john
4 2020-09-12 14:11:19 john
Want to show result in which the difference between 2 rows is greater than 30 days
Expected Output : -
id created_on name
2 2020-11-08 14:11:19 john
4 2020-09-12 14:11:19 john
I have tried with below query but failed as it shows all the data.
SELECT id
, name
FROM
( SELECT MIN(created_on) start_time
, id
, name
FROM table1
WHERE name = 'john'
GROUP
BY id
) start_action
JOIN
( SELECT MAX(created_on) close_time
, id
, name
FROM table1
WHERE name = 'john'
GROUP
BY id
) close_action
USING (id,name)
WHERE name = 'john'
I am using Mysql 5.6 version Request to please help

You could use LEAD here for a MySQL 8+ solution:
WITH cte AS (
SELECT *, LEAD(created_time) OVER (ORDER BY id) lead_created_time,
LAG(created_time) OVER (ORDER BY id) lag_created_time
FROM yourTable
)
SELECT id, created_time
FROM cte
WHERE ABS(DATEDIFF(lead_created_time, created_time)) > 30 OR
ABS(DATEDIFF(lag_created_time, created_time)) > 30;
Demo

Related

How to select specific rows from MYSQL using PHP?

I have a chat app and I'm using PHP to get the data from MYSQL. I don't know how to word this the best way so I'm going to illustrate it the best way I can. Below is the an example the database setup.
DATABASE
ID MESSAGE DATETIME
------------------------------------------
1 Hello1. 2019-04-23 23:04:31
1 Hello2. 2019-03-23 10:04:31
1 Hello3. 2019-04-26 22:04:31
1 Hello4. 2019-04-23 13:01:10
2 Hello5. 2019-04-09 23:04:31
2 Hello6. 2019-04-23 23:04:31
2 Hello7. 2019-04-12 23:04:12
2 Hello8. 2019-04-11 20:04:31
3 Hello9. 2019-05-18 19:04:29
3 Hello10. 2019-02-22 23:04:31
3 Hello11. 2019-03-25 23:04:30
4 Hello12. 2019-04-23 15:04:31
4 Hello13. 2019-04-10 23:04:31
5 Hello14. 2019-01-14 23:04:31
SHOULD SELECT
ID MESSAGE DATETIME
------------------------------------------
1 Hello3. 2019-04-26 22:04:31
2 Hello6. 2019-04-23 23:04:31
3 Hello9. 2019-05-18 19:04:29
4 Hello12. 2019-04-23 15:04:31
5 Hello14. 2019-01-14 23:04:31
What I am trying to do is select the newest ID once for each different ID. So for ID 1 I would only be selecting the one with the newest DATETIME and so on and so forth.
mysql_query("SELECT * FROM messages WHERE ____?____ ORDER BY __?__");
So in this case there should only be 5 results. One of each id with the newest dateline. Any help would be greatly appreciated. Thanks.
You want the MAX(date) value, but one per ID. Because you also want the message, which does not appear in the GROUP BY clause, you should run a join on the table towards itself.
In the joined table, you get the maximum date and the ID, grouped by the ID - this gives you the highest date for each ID. Join that on your table on the ID and date, which allows you to get other columns that do not exist in the GROUP BY (as this GROUP BY is in the joined table, you don't need it in the main table).
SELECT m.id, m.message, m.date
FROM messages m
JOIN (
SELECT id, MAX(date) AS date
FROM foo
GROUP BY id
) AS t
ON m.id=t.id AND m.date=t.date
SQL fiddle shows the live result http://sqlfiddle.com/#!9/c70c3/7
You could try sorting them in a subquery before grouping by the ID as follows:
SELECT * FROM (SELECT * FROM messages ORDER BY DATETIME DESC) AS sortedMessages GROUP BY ID;
OR
mysql_query("SELECT * FROM (SELECT * FROM messages ORDER BY DATETIME DESC) AS sortedMessages GROUP BY ID;");
Or you could build a second table with conversations , that could have a subject and the latest message in the row , and then you would just return that full table, when opening the conversation you would pull the indivual messages from the messages table based on the conversationID

SQL: Get unique data between two dates

Hi I am using a mysql table "student" which has 4 columns:
Id Name Date StudentId
1 John 2010-01-15 3
2 Matt 2010-01-10 5
3 Jane 2010-02-10 8
4 John 2010-02-11 3
5 Matt 2010-02-11 5
6 Jane 2010-02-11 8
I want to fetch only new entries in the table between 2010-02-10 and 2010-02-12. If a student had a previous entry in the table then the query should not return that value. So in the above case the query should only return both entries of Jane since John and Matt had an entry each previous to the date specified.
This is what I have but it is not working:
SELECT * FROM student
WHERE date(Date)
between '2010-02-10' and '2010-02-12'
and date(Date)
not between '0000-00-00' and '2015-02-09';
GROUP BY and HAVING is what you are looking for if you want single record per student:
SELECT * FROM student
GROUP BY Name
HAVING DATE(Date) BETWEEN '2010-02-10' AND '2010-02-12';
Or I would use subquery if you want all the records:
SELECT * FROM student
WHERE DATE(Date) BETWEEN '2010-02-10' AND '2010-02-12'
AND Name NOT IN
(SELECT DISTINCT Name FROM student WHERE DATE(Date) < '2010-02-10');
How it works:
the subquery selects all the names that have records prior to the date range, i.e. the ones you don't want in your result. It produces set like ('John', 'Matt'). The main query then selects all the records in the given date range where Name NOT IN ('John', 'Matt').

Number of 1 time,2 times, 3 times, n times column entries in table in php mysql

Have Table :
id userid type created_date
1 4353535 1 04-06-2014
2 4353536 0 06-06-2014
3 4353537 1 11-06-2014
4 4353538 1 11-06-2014
5 4353539 0 19-06-2014
7 4353541 1 01-06-2014
10 4353544 1 12-06-2014
11 4353535 1 06-06-2014
12 4353536 1 10-06-2014
13 4353537 1 12-06-2014
What I Want : (with in date range)
How much user have single time entry with type 1
How much user have double time entry with type 1
How much user have triple time entry with type 1
How much user have four time entry with type 1
How much user have n time entry with type 1
(PHP & MYSQL)
First get the count for each user, then from that group the entrycount you can get your expected output
select EntryCount, count(userid) from (Select userid, count(id) as Entrycount from myentry group by userid where type=1) as sq group by Entrycount
This will work try
First, get the number of entries per user. Then, get the number of users grouped by number of entries.
SELECT numEntries, COUNT(*) AS numUsers
FROM (
SELECT userid, COUNT(*) AS numEntries
FROM tablename
WHERE type = 1
GROUP BY userid
) tbl
GROUP BY numEntries
Simplified demo
Demo with your data

Selecting a distinct value and the sum of times it shows up in a column

I have an existing table with millions of entries (growing) that consists of:
userid|name|etc...
1 frank ...
1 frank ...
2 joe ...
5 sam ...
1 franky ...
What I need to do is return a table of:
place|name|total
1 franky 3
2 sam 1
3 joe 1
Where total is the SUM(userid = the distinct userid).
Currently I'm doing a query to SELECT DISTINCT userid from table and then foreach returned value in php, I'm doing another query to return the name and sum(userid = userid).
As you can assume, this is very taxing and takes a long time now with all of the values. Is there any way to speed this up by doing 1 query?
i think you need
SELECT #a:=#a+1 AS `place`, name, COUNT(userid) AS `total`
FROM `your_table`, (SELECT #a:= 0) AS a
GROUP BY userid
SELECT userid, COUNT(*)
FROM some_table
GROUP BY userid

problem with result order on distinct select query

i have a table like this
id name date group_id
1 n1 1 1
2 n2 1 1
3 n4 2 2
4 n5 2 2
i want ton write a query to return the group_id without duplicate ordered by date ASC
$query = " SELECT DISTINCT group_id FROM table ORDER BY date ASC";
this query will return 2 , 1 but this query is just going to consider date of the first row of each group_id to order the results
like if i have table like this
id name price date group_id
1 n1 2300 1 1
2 n2 3000 3 1
3 n4 4000 2 2
4 n5 2000 2 2
second row with with '1' as group_id has the biggest date so i should get 1,2 as result but query doesn't care about second row with the '1' group_id and still return 2,1
it only cares about the first row of each id for ordering the results
hopefully there is a easy way to solve this and i dont need to do something wird like putting everything in the 2d array and order that then deleting duplicates
Try this
select group_id,max(date) as SortDate
from table
group by group_id
order by SortDate
If I understand your problem, it sounds like you need to group by the date first.
SELECT group_id
FROM (
SELECT
group_id,
min(date) as min_date
FROM table
GROUP BY group_id
) as t
ORDER BY t.min_date;

Categories