Get user who had no activity in from last 12 months - mysql

I want to make SQL that will return users who not performed any points/redeem activity in last 12 months
user_data
userId email create_date
1 steve#gmail.com 2017-01-05 12:55:00
2 mark_nel#gmail.com 2019-05-15 12:13:00
3 les.born#gmail.com 2018-04-05 03:15:00
points_data
id user_id activity_id activity_points create_date
1 1 1 10 2017-01-05 11:09:00
2 2 1 15 2019-06-12 09:17:00
3 2 2 10 2019-08-05 02:55:00
4 3 1 10 2019-01-05 07:15:00
redeem_data
id user_id redeem_points create_date
1 2 20 2019-09-11 02:55:00
Result
email
steve#gmail.com

Use LEFT JOIN concept to include non matching row from table user_data and only select non matching row by removing matching rows using where id of both tables(points_data,redeem_data) is null.
SELECT u.email
FROM user_data u
LEFT JOIN points_data p ON u.userId = p.user_id AND p.create_date >= CURRENT_DATE - INTERVAL 1 YEAR
LEFT JOIN redeem_data r ON u.userId = r.user_id AND r.create_date >= CURRENT_DATE - INTERVAL 1 YEAR
WHERE p.id IS NULL AND r.id IS NULL;

Related

How to fetch count from the sub-table with multiple date

I have a user table
id
name
number
created_at
1
User1
102
2022-02-03
2
User2
103
2022-02-06
3
User3
123456
2022-02-07
4
User4
1234567
2022-02-07
5
User5
1234568
2022-04-08
and invite table
id
invited_by
invited_to_number
created_at
1
1
123456
2022-04-05 12:03:03
2
2
123456
2022-04-05 17:13:23
2
1
1234567
2022-04-07 17:13:23
2
1
1234568
2022-04-07 17:13:23
2
2
1234565
2022-04-08 17:13:23
I need user table records along with the count of all invited registered in
all-time accepted in
Today accepted in
yesterday accepted in
with the group by number using MySQL Query
Count will only go to those users who were invited first
and after successfully registered count will add to the invited the user
So, the Expected result is
Today Date: 2022-04-08
id
name
all_time_accepted
Today's accepted
yesterday accepted
1
User1
3
1
1
2
User2
0
0
0
3
User3
0
0
0
4
User4
0
0
0
5
User5
0
0
0
If you want to count only today's or yesterday's invites, place a boolean condition (like DATE(i.created_at) = #today_date) inside the select expression. The condition will evaluate to 1 (if true) or 0 (if false), which means that if you SUM(), you will get the number of rows satisfying this condition.
SELECT
u.id,
u.name,
SUM(
u1.id IS NOT NULL
AND i1.id IS NULL
) AS all_time_accepted,
IFNULL(SUM(
u1.id IS NOT NULL
AND i1.id IS NULL
AND DATE(i.created_at) = #today_date
), 0) AS today_accepted,
IFNULL(SUM(
u1.id IS NOT NULL
AND i1.id IS NULL
AND DATE(i.created_at) = #today_date - INTERVAL 1 DAY
), 0) AS yesterday_accepted
FROM
(SELECT #today_date := CURDATE()) AS var,
`user` u
LEFT JOIN `invite` i
ON i.invited_by = u.id
LEFT JOIN `user` u1
ON u1.number = i.invited_to_number
LEFT JOIN `invite` i1
ON i1.invited_to_number = i.invited_to_number
AND i1.created_at < i.created_at
GROUP BY u.id

mysql select 2 table based on date and combine each other

i Need some help.. i have some case like this below
i have 2 table.. call ("in_table" and "out_table")
data "in_table" look like
stock_id item_id date qty_in
-----------------------------------------
1 11 2017-07-11 12
2 11 2017-07-11 10
3 12 2017-07-11 10
4 12 2017-07-19 10
And i have "out_table" is like
id_tr item_id date qty_out
-------------------------------------
1 11 2017-07-19 2
1 12 2017-07-19 1
2 11 2017-07-19 2
2 12 2017-07-19 1
And i want to combine the date and display all the data like this,
Update: the join is by item_id but i want to select by date
date item_id qty_in qty_out
---------------------------------------
2013-07-11 11 22 0
2013-07-11 12 10 0
2013-07-19 11 0 4
2013-07-19 12 10 2
Thank you for your help.
It looks like you need kind of a full outer join of two aggregate subqueries. But in your case I would get item_id and date in a union subquery (derived table) and the sums in correlated subqueries (subselect).
select item_id, date,
(select sum(qty_in) from in_table i where i.item_id = sub.item_id and i.date = sub.date) as qty_in,
(select sum(qty_out) from out_table o where o.item_id = sub.item_id and o.date = sub.date) as qty_out
from (
select item_id, date from in_table
union
select item_id, date from out_table
) sub
order by date, item_id

MySql update table from another one join and group by

If I have table logs :
ID Date P_id TYPE
-------------------------------
1 2016-9-1 11 adClick
2 2016-9-1 22 adComplete
3 2016-9-1 11 adComplete
4 2016-9-3 22 adClick
5 2016-9-3 22 adClick
6 2016-9-1 44 adClick
7 2016-9-3 44 adComplete
8 2016-9-3 44 adClick
9 2016-9-3 11 adClick
-------------------------------
and another table report having the same Date & P_id as follows :
ID Date P_id clicks
--------------------------------
1 2016-9-1 11
2 2016-9-1 11
3 2016-9-1 22
4 2016-9-3 22
5 2016-9-1 11
6 2016-9-1 44
5 2016-9-1 44
6 2016-9-1 11
---------------------------------
I need MySQL query to fill clicks in report table and according to the key (Date & P_id) :
clicks =
count of rows having (Date & P_id) in Report table
divided by
count of rows having (Date & P_id) and Type is adClick
So the table will be :
ID Date P_id clicks
--------------------------------
1 2016-9-1 11 4 / 1
2 2016-9-1 11 4 / 1
3 2016-9-1 22 0
4 2016-9-3 22 2 / 2
5 2016-9-1 11 4 / 1
6 2016-9-1 44 2 / 1
5 2016-9-1 44 2 / 1
6 2016-9-1 11 4 / 1
---------------------------------
Sample, first row :
2016-9-1 11 4 / 1
4 rows (2016-9-1 11) in report table by
1 row (2016-9-1 11) in logs table with type=adClick
What I have tried so far :
UPDATE report AS r
INNER JOIN
(
SELECT
*, count(id) AS count_value
FROM
logs
WHERE
type= "adClick"
GROUP BY
date,p_id
) log
ON r.date=log.date AND r.p_id=log.p_id
SET r.clicks=(log.count_value / (SELECT COUNT(lof) from report) );
Thanks in advance
You can do this using conditional aggregation:
UPDATE report AS r INNER JOIN
(SELECT date, p_id, count(*) AS cnt,
SUM(type = 'adClick') as cnt_adclick
FROM logs
GROUP BY date,p_id
) l
ON r.date = l.date AND r.p_id = l.p_id
SET r.clicks = cnt_adclick / cnt;
You can also do this with avg() instead of division:
UPDATE report AS r INNER JOIN
(SELECT date, p_id,
AVG(type = 'adClick') as avg_clicks
FROM logs
GROUP BY date,p_id
) l
ON r.date = l.date AND r.p_id = l.p_id
SET r.clicks = avg_clicks;
Try using CONCAT()
UPDATE report AS r
INNER JOIN (
SELECT
date,
p_id,
count(*) AS count,
SUM(type = 'adClick') AS count_adclick
FROM
logs
GROUP BY
date,
p_id
) log ON r.date = log.date
AND r.p_id = log.p_id
SET r.clicks = CONCAT(log.count_adclick, ' / ', log.count);
Thanks all, the following did the job for me :
UPDATE report AS r
INNER JOIN
(
SELECT cnt_adclick,count(*) as cnt_report,date, report.P_id
FROM report
INNER JOIN
(
SELECT date as date, P_id, SUM(event_type = 'adClick') as cnt_adclick
FROM logs
GROUP BY date,P_id
) inner_log
ON report.date = inner_log.date AND report.P_id = inner_log.P_id
GROUP BY report.date, report.P_id
) l
ON r.date = l.date AND r.P_id= l.P_id
SET r.clicks = cnt_adclick / cnt_report;

Mysql SUM 0 when not in another table

I have 2 tables:
users:
id | name | club_id |
1 Bob 4
2 Jane 5
3 Alex 4
4 Paul 4
5 Tom 4
points:
user_id | club_id | amount(can vary)
1 4 10
1 2 10
2 5 10
3 4 10
3 4 10
4 4 10
3 2 10
3 4 10
I need (where users.club_id = 4 AND points.club_id = 4):
user_id | name | sum(amount)
3 Alex 30
1 Bob 10
4 Paul 10
5 Tom 0
Notice Tom is present in users but doesn't have any entries in points, so his sum should be 0. This is what throws me off in conjuction with grabbing a list from users.
Also would like this to be as efficient as possible (hence I added club_id = 4 both in users and points)
Try this:
SELECT
u.id,
u.name,
COALESCE(SUM(p.amount), 0) AS Totalpoints
FROM
(
SELECT *
FROM users
WHERE club_id = 4
) AS u
LEFT JOIN
(
SELECT *
FROM points
WHERE club_id = 4
) AS p ON p.user_id = u.id
GROUP BY u.id,
u.name;
See it in action here:
SQL Fiddle Demo
try this query
select u.id, u.name, sum(if (p.amount is null, 0, p.amount)) as totalPoint
from
user u
left join
(select * from point p where p.club_id = 4)p
on u.id = p.user_id
where u.club_id=4
group by u.id
SQL FIDDLE:

how to use joins in my sql?

there are two tables tbldoctor and tblschedule
tbldoctor
doc_id(PK) docMrId docfname
1 22 manish
2 23 rahul
3 22 ashish
4 24 ahemad
5 22 narendra
6 22 akshat
tblschedule
doctor_id(FK) mr_id schedule_date
1 22 2012-06-12
1 22 2012-06-13
3 22 2012-06-14
3 22 2012-06-14
4 24 2012-06-12
4 24 2012-06-12
5 22 2012-06-14
5 22 2012-06-15
5 22 2012-06-12
What i want is list of all doctorid and the count of particular doctor repeated in tblschedule table where schedule_date parameter and mr_id is provided here we are supposed mr_id =22 and schedule_date between 2012-06-01 to 2012-06-31
Output Should look like
doc_id docfname count
1 manish 2
3 rahul 2
5 narendra 3
6 akshat 0
select d.doc_id, docfname, count(mr_id) as count
from tbldoctor d
left outer join tblschedule s on s.doctor_id = d.doc_id
where mr_id = 22
and schedule_date between '2012-06-01' and '2012-06-31'
group by s.doctor_id
edit
select d.doc_id,
docfname,
sum(case when mr_id = 22
then 1
else 0
end) as count
from tbldoctor d
left outer join tblschedule s on s.doctor_id = d.doc_id
and schedule_date between '2012-06-01' and '2012-06-31'
group by s.doctor_id
SQLFiddle example
edit 2
how about
select d.doc_id, docfname, count(mr_id) as count
from tbldoctor d
left outer join tblschedule s on s.doctor_id = d.doc_id and mr_id = docmrid
where docmrid = 22
and (schedule_date between '2012-06-01' and '2012-06-31' or mr_id is null)
group by s.doctor_id
order by d.doc_id
SQLFiddle example
Not 100% sure I've understood you, but this will give you a list of all doctor IDs, along with the number of schedule items for each in between two given dates.
SELECT tbldoctor.doc_id, COUNT(*) cnt
FROM tbldoctor d INNER JOIN tblschedule s
ON d.doc_id = s.doctor_id
WHERE s.schedule_date BETWEEN '2012-06-12' AND '2012-06-15'
GROUP BY tbldoctor.doc_id
SELECT * FROM `tbldoctor` JOIN `tblschedule` ON `tblschedule`.doctor_id(FK) = `tbldoctor`.doc_id(PK)
SELECT tbldoctor.doc_id, COUNT(*) cnt FROM tbldoctor d INNER JOIN tblschedule s ON d.doc_id = s.doctor_id WHERE s.schedule_date BETWEEN '2012-06-12' AND '2012-06-15' GROUP BY tbldoctor.doc_id