Group similar items - mysql

Here is my table structure with data
id actor_id created_at updated_at
729 80 2012-09-10 17:05:59 2012-09-10 17:05:59
731 80 2012-09-10 17:04:02 2012-09-10 17:04:02
725 139 2012-09-06 13:59:08 2012-09-06 13:59:08
724 76 2012-09-06 11:31:30 2012-09-06 11:31:30
723 29 2012-09-06 09:40:22 2012-09-06 09:40:22
719 29 2012-09-06 09:24:02 2012-09-06 09:24:02
811 80 2012-09-02 17:05:59 2012-09-10 17:05:59
812 80 2012-09-01 17:04:02 2012-09-10 17:04:02
This is the result of
SELECT `te`.`id`, te.actor_id, te.created_at, te.created_at
FROM `timeline_events` AS te
ORDER BY
te.created_at DESC
LIMIT 10
I need group it by actor_id and created_at
Here is what i need in the end
id actor_id created_at updated_at count
729 80 2012-09-10 17:05:59 2012-09-10 17:05:59 2
725 139 2012-09-06 13:59:08 2012-09-06 13:59:08 1
724 76 2012-09-06 11:31:30 2012-09-06 11:31:30 1
723 29 2012-09-06 09:40:22 2012-09-06 09:40:22 2
812 80 2012-09-10 17:04:02 2012-09-10 17:04:02 2
Can someone guide me how to do this?
Many thanks in advance
UPD To simplify i will put another example
So say i have next rows
1 1 (count: 2)
1
3 3 (count: 1)
4
4 => after magic function it should be 4 (count: 2)
1
1 1 (count: 3)
1
6 6 (count: 2)
6
4 4 (count 3)
4
4
So it should split by groups.
UPD 2
I need this query for rendering timeline. Right now it show all info what user did, but i need group it.
Before
user1 upload photo
user1 changed information
user2 updated bio
user3 uploaded photo
user3 updated bio
user1 update bio
After
user1 uploadd photo and changed infomarion
user2 updated bio
user3 uploaded photo and updated bio
user1 updated bio

I think this might be what you are trying to do:
select t1.id,
t1.actor_id,
max(created_at) created_at,
updated_at,
t2.total
from yourtable t1
left join
(
select count(*) total, date(created_at) dt, actor_id
from yourtable
group by actor_id, date(created_at)
) t2
on t1.actor_id = t2.actor_id
and date(t1.created_at) = t2.dt
group by t1.actor_id, date(t1.created_at)
order by t1.created_at desc
see SQL Fiddle with demo
I am grouping by actor_id and the date using the DATE() function

I find solution by myself
Here is the query
SET #i = 0;
SELECT
COUNT(`wrapper`.`id`) AS 'count',
GROUP_CONCAT(`wrapper`.`type` SEPARATOR ',') as 'types'
FROM (
SELECT
#prev := (
SELECT prev_te.actor_id
FROM `timeline_events` AS prev_te
WHERE prev_te.created_at > te.created_at
ORDER BY prev_te.created_at ASC
LIMIT 1
) AS 'prev_actor_id',
IF(
#prev = te.`actor_id` OR #prev IS NULL,
#i,
#i := #i + 1
) AS 'actor_id_group',
`te`.*
FROM `timeline_events` AS te
ORDER BY
te.created_at DESC,
te.id DESC
) AS `wrapper`
GROUP BY `wrapper`.`actor_id_group`
LIMIT 10
And here is the proof link ;-)
This website really helped me
I am using wrapper for grouping purpose, because mysql didn't group by variables, if someone know better solution, please let me know

SELECT te.id, te.actor_id, te.created_at, te.updated_at ,
COUNT(*) FROM timeline_events AS te GROUP BY te.actor_id,
te.created_at ORDER BY
te.created_at DESC
LIMIT 10

Add GROUP BY actor_id before order by clause.
Latest edit:
select distinct actor_id, count(actor_id), created_at from actors group by actor_id
order by created_at desc;

Related

How can I get the sum of a row using LIMIT

id
reg_No
Subj_id
sub_title
score
Class_id
1
98
23
MATHEMATICS
90
2
2
98
21
ENGLISH LANG
60
2
3
98
24
PHYSICS
78
2
4
98
23
CHEMISTRY
100
2
5
98
21
BIOLOGY
81
2
6
98
24
AGRICULTURE
87
2
I want to select the best SUM(score) of the four(4) subjects including English and mathematics.
It suppose to sum 90+60+100+87 = 337
But, it's summing the entire column
Here is my query
SELECT SUM(score)
FROM table1
WHERE reg_no = 98
AND class_id=2
ORDER BY CASE WHEN sub_title IN ('English Language','Mathematics')
THEN 0
ELSE 1 END, score DESC LIMIT 4
The priority of SELECT is higher than LIMIT, therefore, you have to use a subquery
SELECT sum(score)
FROM
(
SELECT *
FROM tab
WHERE reg_no = 98 AND class_id=2
ORDER BY CASE WHEN sub_title IN ('English Language','Mathematics')
THEN 0
ELSE 1 END, score DESC
LIMIT 4
) t
DEMO
An easy way to split into two queries. The first one gets the Math and English score values, and the second one gets the two highest scores from the remaining values.
SQL Server:
With CTE As (
Select Top 2 Score From table1 Where reg_no = 98 And class_id=2 And sub_title Not In ('MATHEMATICS','ENGLISH LANG')
Order by Score Desc
Union All
Select Score From table1 Where reg_no = 98 And class_id=2 And sub_title In ('MATHEMATICS','ENGLISH LANG')
)
Select Sum(Score)
From CTE
MySQL:
With CTE As (
Select Score
From
(Select Score From table1 Where reg_no = 98 And class_id=2 And sub_title Not In ('MATHEMATICS','ENGLISH LANG')
Order by Score Desc
Limit 2) As S
Union All
Select Score From table1 Where reg_no = 98 And class_id=2 And sub_title In ('MATHEMATICS','ENGLISH LANG')
)
Select Sum(Score)
From CTE

MySQL last 50 records

I have to get the last 50 records from my MySQL database.
Here is the structure of my test database:
ID S1 S2 S3 Date-time Label
13 32 55 33 2017-09-05 13:15:06 temperature
16 111 222 66 2017-09-05 19:22:14 temperature
17 44 55 33 2017-09-05 19:22:14 temperature
18 55 11 88 2017-09-12 14:22:00 temperature
21 77 1 200 2017-09-15 12:24:06 temperature
22 22 55 11 2017-09-19 14:37:00 temperature
How could I show only the last 3 data? for example:
18 55 11 88 2017-09-12 14:22:00 temperature
21 77 1 200 2017-09-15 12:24:06 temperature
22 22 55 11 2017-09-19 14:37:00 temperature
Greetings and thank you.
In Oracle12c you can use the fetch keywork:
SELECT *
FROM table
ORDER BY id DESC
FETCH FIRST 50 ROWS ONLY;
FOR ORACLE:
SELECT * FROM (
SELECT ID,
S1,
S2,
S3,
Date-time,
Label
FROM TABLE
ORDER BY ID DESC)
WHERE ROWNUM <= 50;
FOR MYSQL:
SELECT ID,
S1,
S2,
S3,
Date-time,
Label
FROM TABLE
ORDER BY ID DESC
LIMIT 50;
Here is a quick doc:
https://www.w3schools.com/sql/sql_top.asp
Edit:
For the last 50 rows:
SELECT * FROM (
SELECT * FROM table ORDER BY id DESC LIMIT 50
) sub
ORDER BY id ASC
Use Top N Query (row num<=50) fro first, for last 50 you can use "order by id desc"
First I was confused with the Post between ORACLE and MYSQL I apologize.
The solution at the end was the following:
SELECT * FROM inv ORDER BY id DESC LIMIT 50
then transform the ARRAY that I collect with the function:
var dorde = d0.reverse ();
thanks for everything.

select unique row as per latest created_at time

this is my query:
SELECT br.employee_id AS rat_id,
br.rating_comment,
br.created_at,
br.id
FROM employee_followers
LEFT JOIN employee_ratings AS br ON employee_followers. employee_id = br.employee_id
WHERE employee_followers.employee_id IN
(SELECT `employee_id`
FROM employee_followers
WHERE user_id =32)
GROUP BY br.id
ORDER BY created_at DESC
what I am getting:
rat_id rating_comment created_at id
18 superb developer 2016-02-19 18:26:54 82
9 james to manoj-joshi 2016-02-19 16:42:17 84
50 james to prem 2016-02-19 13:05:30 83
50 pinal to prem 2016-02-19 12:20:00 73
50 prem to premal-joshi 2016-02-19 11:40:52 78
18 prem to mukund 2016-02-19 11:21:52 77
18 pinal to mukund 2016-02-18 11:37:00 76
9 mukund rate to mitesh 2016-02-15 22:34:14 51
9 Not a bad. 2016-02-10 00:16:31 45
9 sda 2016-02-08 01:36:33 39
what I want:
rat_id rating_comment created_at id
18 superb developer 2016-02-19 18:26:54 82
9 james to manoj-joshi 2016-02-19 16:42:17 84
50 james to prem 2016-02-19 13:05:30 83
Try This
SELECT rat_id,rating_comment, MAX(created_at) AS created, id FROM (
SELECT br.employee_id AS rat_id,
br.rating_comment,
br.created_at,
br.id
FROM employee_followers
LEFT JOIN employee_ratings AS br ON employee_followers. employee_id = br.employee_id
WHERE employee_followers.employee_id IN
(SELECT `employee_id`
FROM employee_followers
WHERE user_id =32)
GROUP BY br.id
ORDER BY created_at DESC) AS temp GROUP BY temp.rat_id
It seems that you want only the latest record per employee_id. You can use a derived table to get the maximum date, then join again to get all fields from employee_ratings table for this date:
SELECT er.employee_id AS rat_id,
er.rating_comment,
er.created_at,
er.id
FROM employee_followers AS ef
LEFT JOIN (
SELECT employee_id, MAX(created_at) AS max_date
FROM employee_ratings
GROUP BY employee_id
) AS emp_max ON ef.employee_id = emp_max.employee_id
LEFT JOIN employee_ratings AS er
ON emp_max.employee_id = er.employee_id AND
emp_max.max_date = er.max_date
WHERE user_id = 32
ORDER BY created_at DESC
I have also removed GROUP BY br.id that seems to be redundant in the context of the query. Also IN operator can be replaced by user_id = 32 since you are selecting from the same table.

Conditional SQL Query on Multiple Rows

I am trying to find out which customers have defaulted on their loans. I would like to query the dataset to find the User_id of customers who have not paid in the last 60 days, but and not sure how to implement this in SQL.
User_id Due_Date Loan_Amount Paid_Amount
1 2012-04-04 16:14:12 500 40
1 2012-05-04 16:14:12 500 40
1 2012-06-04 16:14:12 500 0
1 2012-07-04 16:14:12 500 0
1 2012-08-04 16:14:12 500 0
2 2012-02-15 03:30:55 2030 100
2 2012-03-15 03:30:55 2030 100
2 2012-04-15 03:30:55 2030 100
3 2012-01-03 12:24:42 777 10
3 2012-02-03 12:24:42 777 0
3 2012-03-03 12:24:42 777 0
3 2012-04-03 12:24:42 777 0
In pseudocode (shown in bold) would look something like this, but I can't seem to implement it in MySQL:
SELECT User_id from TABLE_NAME WHERE Loan_Amount > 0 AND [the value Paid_Amount has been null for over 60 days]
Desired Output:
Users 1 and 3 in the above query would be returned because they have not paid for three consecutive periods.
NOTE: Due_Date is a time stamp
Any ideas would be very much appreciated!
Looks like you can use the DATEDIFF(date1, date1) function to obtain a list of delinquent borrowers.
SELECT DISTINCT
user_id
FROM table_name n
JOIN (SELECT user_id, max(due_date) maxDate FROM table_name GROUP BY user_id) t
ON n.user_id = t.user_id
AND n.due_date = t.maxDate
WHERE
loan_amount > 0
AND paid_amount IS NULL
AMD DATEDIFF(due_date, getdate()) > 60
My previous query was wrong, try this
select distinct t1.User_id
from TABLE_NAME t1
inner join (
select ts1.User_id, sum(ts1.Paid_Amount) as Paid_Amount_Total
from TABLE_NAME ts1
group by ts1.User_id
) t2
on t1.User_id=t2.User_id and t1.Loan_Amount>t2.Paid_Amount_Total
)
where
t1.Loan_Amount > 0
and t1.User_id not in (
select ts2.User_id
from TABLE_NAME ts2
where ts2.Due_Date>=DATE_SUB(NOW(), INTERVAL 60 DAY) and ts2.Paid_Amount>0
)
t1, ts1, ts2 - are aliases for TABLE_NAME

How to get date_of_highest_points

I have still problem with select date_of_highest_points:
$qry1 = mysql_query("INSERT INTO bbdnes_hraci (nick, sumfrags, sumpoints,
sumhours, lastdate1, highest_points, date_of_highest_points)
SELECT DISTINCT nick, SUM(frags), SUM(points), SUM(hours),
MAX(lastdate), MAX(points), ??????
FROM hraci
GROUP BY nick ");
I asked about that here https://stackoverflow.com/questions/18817900/select-in-select , but i have not solved it, despite council. Can somebody help me with code?
TABLE: hraci
nick frags points hours lastdate
Gamer1 20 100 1 2013-09-17 22:16:08
Gamer1 30 150 3 2013-09-18 20:17:15
Gamer1 25 125 0.5 2013-09-18 23:16:06
Gamer2 50 250 4 2013-09-17 21:11:30
Gamer2 5 25 2 2013-09-17 23:13:59
Need get:
TABLE: bbdnes_hraci
nick sumfrags sumpoints sumhours lastdate1 highest_points date_of_highest_points
Gamer1 75 375 4.5 2013-09-18 23:16:06 150 2013-09-18 20:17:15 ??
Gamer2 55 275 6 2013-09-17 23:13:59 250 2013-09-17 21:11:30 ??
You can do something like this:
select nick, SUM(frags) sumfrags, SUM(points) sumpoints, SUM([hours]) sumhours, max(lastdate) lastdate, max(points) highest_points
into #t1
from hraci
group by Nick
select t1.*, x.lastdate date_of_highest_points
from #t1 t1
outer apply
(select top 1 lastdate
from hraci t
where t.Nick = t1.Nick and t.points = t1.highest_points
order by t.lastdate desc) x
try this
select * from table_name where highest_points = (select max(highest_points) from table_name)
Untested:
SELECT DISTINCT nick, SUM(frags), SUM(points), SUM(hours),
MAX(lastdate), MAX(highest_points),
(
SELECT lastdate As date_of_highest_points
FROM hraci
WHERE points =(SELECT MAX(points) FROM hraci)
)
(rest of query. i.e. FROM and ORDER By's)