mySql query higher then last user comment - mysql

I have the following table:
id post_id user_id to_user_id date time
---- ---------- -------- ------------ ------
1 100 1 2 10:00
2 100 1 2 10:30
3 100 2 2 11:00
4 100 5 2 11:30
5 100 8 2 11:45
6 105 10 50 09:00
7 105 2 50 09:30
8 105 11 50 11:00
9 105 30 50 11:30
10 105 32 50 11:45
On the following table you can see that user_id 2 has comments for post 100 and 105.
I need to get only the records per post_id that is hight than the first comment he wrote.
so for this example the result will be records 4 and 5 for post 100 and 8, 9, 10 for post 105 because 4, 5 is bigger than 3 (first record for user_id 2)
and 8, 9, 10 is bigger than 7 (user_2 first comment)
clear expected result:
id post_id user_id to_user_id date time
4 100 5 2 11:30
5 100 8 2 11:45
8 105 11 50 11:00
9 105 30 50 11:30
10 105 32 50 11:45

Could be with a subselect and an aggregation function
select * from my_table
where ( post_id, date_time) > (select post_id, max( date_time)
from my_table where user_id =2
group y post_id);
or if the tuple version donìt work properly try
select * from my_table as m
inner join (select post_id, max( date_time)
from my_table where user_id =2
group y post_id ) t on m.post_id = t.post_id
where m.date_time > t.date_time

Related

MySQL: select sum of column having specific values

What I'm trying to do is to select a specific amount of tickets (max 2) and every person that has the sum of the number of tickets less of 3 and the valid field has to be != 'e'
I have this table:
ID
id_person
nr_tickets
valid
1
220
1
s
2
220
1
s
3
330
2
s
4
330
1
e
5
331
1
s
6
220
2
s
7
441
1
s
8
442
2
s
9
443
1
s
10
444
1
s
11
445
2
s
Here is what I did:
SELECT m.id, m.id_person, m.nr_tickets, m.valid
FROM table m
JOIN table m1 ON m1.id <= m.id
WHERE m.nr_tickets > 0
GROUP BY m.id
HAVING SUM(case when m.valid != 'e' then m1.nr_tickets end) <= 10
This query gives me
ID
id_person
nr_tickets
valid
1
220
1
s
2
220
1
s
3
330
2
s
5
331
1
s
6
220
2
s
7
441
1
s
8
442
2
s
As you can see the query it's almost right, the thing is that the person 220 in the results has the sum of the tickets is greater than 2.
What I'm trying to achieve is to bypass the ID 6, and to have instead the ID 9
select `id`,`id_person`, sum(`nr_tickets`) as `nr_tickets`, `valid`
from `test`
group by `id_person`
having sum(`nr_tickets`) < 3 and `valid`!="e"
Output:
id id_person nr_tickets valid
5 331 1 s
7 441 1 s
8 442 2 s
9 443 1 s
10 444 1 s
11 445 2 s

Count without 2nd subquery in SQL

I am trying to attain the count of users that ordered at least 1 product on multiple days.
Transactions Table
usr_id|transt_id|product_id|spend| transaction_date
4 8 32 40 2020-05-08 17:54:59
4 7 31 20 2020-05-01 17:54:59
4 7 31 40 2020-05-01 17:54:59
4 6 20 30 2020-05-02 17:54:59
4 6 19 20 2020-05-02 17:54:59
4 6 18 10 2020-05-02 17:54:59
3 5 17 20 2020-05-04 17:54:59
3 5 16 10 2020-05-04 17:54:59
2 3 14 30 2020-05-04 18:54:59
2 3 13 50 2020-05-04 18:54:59
1 2 12 30 2020-05-05 20:54:59
1 2 12 40 2020-05-05 20:54:59
1 2 12 40 2020-05-04 20:54:59
1 1 11 20 2020-05-05 21:54:59
1 1 10 40 2020-05-05 21:54:59
3 4 10 60 2020-05-06 17:54:59
Through my code I have been able to reach to a point where the output is:
select user_id, count(*)
from (
select user_id, date(transaction_date)
from transactions
group by user_id, date(transaction_date)) as abc
group by user_id
having count(user_id)>1;
user_id | count
1 2
3 2
4 3
I want to write a code without writing another subquery to get the count of users having count(*)>1;
The output should be: 3.
In other words, I don't want the following code; I want to write one less subquery or a completely new query
select count(*)
from (
select user_id, count(*)
from (
select user_id, date(transaction_date)
from transactions
group by user_id, date(transaction_date)) as abc
group by user_id
having count(user_id)>1) as bcd;
The query that you already have could be written without a subquery:
select user_id, count(distinct date(transaction_date)) count
from transactions
group by user_id
having count(distinct date(transaction_date))>1;
So what you need now can be written with only 1 subquery:
select count(*) count
from (
select user_id
from transactions
group by user_id
having count(distinct date(transaction_date))>1
) t
You can get the same result with EXISTS:
select count(distinct t.user_id) count
from transactions t
where exists (
select 1
from transactions
where user_id = t.user_id and date(transaction_date) <> date(t.transaction_date)
)
See the demo.

Getting result for latest row(based on timestamp column) for each user and each day

I have a table called play_progress.
play_progress
id user_id coins timecreated
1 1 20 2016-01-23 06:55:09
2 1 24 2016-01-23 06:59:22
3 1 28 2016-01-23 07:05:34
4 2 4 2016-01-23 07:10:58
5 2 10 2016-01-23 07:12:08
6 1 32 2016-01-24 00:07:48
7 2 14 2016-01-24 00:12:08
8 1 35 2016-01-24 00:44:48
9 2 18 2016-01-24 00:55:08
I like to get the latest row( based on timecreated) for each day for each user.
I have tried the following query;
SELECT user_id, coins, MAX(timecreated)
FROM player_progress
GROUP BY user_id, DATE(timecreated);
It gives the result for each day but it gives wrong timecreatd value.
Where I am going wrong?
Result details like
id user_id coins timecreated
1 1 28 2016-01-23 07:05:34
5 2 10 2016-01-23 07:12:08
8 1 35 2016-01-24 00:44:48
9 2 18 2016-01-24 00:55:08
I have searched through SO, but couldn't find a solution to my problem.
If you need to fetch more columns then the ones used for grouping (user_id and timecreatd) you need a more complex query:
SELECT p.user_id, p.id, coins, p.timecreated
FROM play_progress p INNER JOIN
(SELECT user_id, MAX(timecreated) as max_time
FROM play_progress
GROUP BY user_id, DATE(timecreated)) pp
ON p.user_id = pp.user_id
AND p.timecreated = pp.max_time;
Here you have a sample

MYSQL group by month but not on first day of month

My table votes contains votes that have been made by users at different times:
id item_id position user_id created_at
1 2 0 1 11/21/2013 11:27
26 1 1 1 11/21/2013 11:27
27 3 2 1 11/21/2013 11:27
42 2 2 1 12/7/2013 2:20
41 3 1 1 12/7/2013 2:20
40 1 0 1 12/7/2013 2:20
67 2 2 1 12/13/2013 1:13
68 1 1 1 12/13/2013 1:13
69 3 0 1 12/13/2013 1:13
84 2 0 1 12/28/2013 2:29
83 3 2 1 12/28/2013 2:29
82 1 1 1 12/28/2013 2:29
113 3 0 1 1/17/2014 22:08
114 1 1 1 1/17/2014 22:08
115 2 2 1 1/17/2014 22:08
138 2 0 1 1/20/2014 16:49
139 1 1 1 1/20/2014 16:49
140 3 2 1 1/20/2014 16:49
141 1 1 11 1/20/2014 16:51
142 3 2 11 1/20/2014 16:51
143 2 0 11 1/20/2014 16:51
I need to tally the results on a monthly basis but here's the tricky part: the start/end of the month does not necessarily fall on the first day of the month. So if the votes are due on the 10th day of every month, I need a vote that was cast on the 10th to be in a different group from a vote that was cast on the 11th. Using the data above, I want to get three groups:
Group 1: 6 votes (11/21 and 12/7)
Group 2: 6 votes (12/13, 12/28)
Group 3: 9 votes (1/17, 1/20)
I've tried a lot of approaches but to no avail. This is my query right now:
select created_at, ADDDATE(DATE_FORMAT(created_at, '%Y-%m-01'),interval 10 day) as duedate,count("id") from votes where list_id = 2 group by duedate
I am getting group sizes of 3, 9, and 9, not 6, 6 and 9. Any help you can provide would be much appreciated. Thanks.
Your query is close. You just need to subtract 9 days (10 - 1) from the current day to get the month:
select created_at, date_sub(created_at, interval 9 day) as duedate,
count(id)
from votes
where list_id = 2
group by duedate;
date_format() converts a date to a string. There is no need to convert a date value to a character value for this query.
EDIT:
To group by month:
select date_format(date_sub(created_at, interval 9 day), '%Y-%m') as YYYYMM,
count(id)
from votes
where list_id = 2
group by YYYYMM;

mysql pivot query and rank Query

I Have a marksheet table like:
ID STUDENT_ID Branch_id Class_id Exam_id Subject_id Numbers Date
1 653 5 1 1 8 60 2012-01-01
2 653 5 1 1 9 40 2012-01-01
3 653 5 1 1 10 80 2012-01-01
4 653 5 1 1 11 50 2012-01-01
5 653 5 1 1 12 65 2012-01-01
6 653 5 1 1 13 33 2012-01-01
7 653 5 1 1 15 86 2012-01-01
8 222 5 1 1 8 100 2012-01-01
9 222 5 1 1 9 80 2012-01-01
10 222 5 1 1 10 92 2012-01-01
11 222 5 1 1 11 50 2012-01-01
12 222 5 1 1 12 65 2012-01-01
13 222 5 1 1 13 33 2012-01-01
7 222 5 1 1 15 86 2012-01-01
I want to get rank I got answer by this question
Also when I fetched all class result I use pivot query:
SELECT stu_id, sum(numbers) AS total, branch_id, depart_id, class_id,
SUM( IF( subject_id =1, numbers, 0 ) ) AS MAth,
SUM( IF( subject_id =2, numbers, 0 ) ) AS Eng,
SUM( IF( subject_id =3, numbers, 0 ) ) AS Science
FROM marksheet where branch_id = 1 AND depart_id = 1
AND class_id = 1 GROUP BY stu_id ORDER BY total DESC
I want to get rank in my class query (pivot query)? And I want to count how many students on first position and how many on second and third?
Required Data sample:
ID Name Math English Science Total Percent Position Rank
Any one help?
I think what you need to do is create a second table with grade boundaries that are being referenced so for instance :
ID grade start_boundry end_boundry
1 A 60 100
ect..
then create a join between the tables and then do a WHERE statement between the Numbers and the start/ end boundries
so ->
SELECT grade FROM boundries_table RIGHT JOIN sudent_table
WHERE boundries_table.start_boundry < student_table.numbers
AND boundries_table.end_boundry > student_table.numbers
i think that should work if my MySQL memory serves, just modify the table to how you need it to run and it should work for how you need it.