Checking users who have only one activity on a job in Mysql - mysql

I have a table called activities.
The Admin gives users Some job With unique code to do.
when a user doing something on one of his jobs. user add one record on table with
unique code job and user_id.
I want to count the number of jobs the user has just done an activity on that.
I want to show something like this :
user_id | Count Jobs with one activity
1 | 5
2 | 7
.....
in this case user with id 1 has 5 jobs that he just do one activity on it.
* one job is blong to one user and another user can not do activity on it.
I'm sorry if my english is not good
there is a sample of activities table :

Here you go.
SELECT user_id, count(*) as Job_counts
FROM activity_table
GROUP BY user_id;

Related

how to select specific rows in some condition

I tried to write a query that selects rows with steps that both user 1 and user 2 did, with combined number of times they did the step (i.e., if user 1 did step 1 3 times and user 2 did 1 time then the count should show 4 times.)
when I put condition as user_id=1, user_id=2 there is no error but it return nothing, when it should return some rows with values.
there is table step, and step taken
and table step has column id, title
table step_taken has column id, user_id(who performs steps), step_id
i want to find step that both of two user whose id 1,2 did
and also want to have the value as count added up how many times they performed that step.
for example if user id 1 did step named meditation 2 times,
and user id 2 did step named meditation 3 times,
the result i want to find should be like below ;
------------------------------
title | number_of_times
------------------------------
meditation| 5
------------------------------
here is my sql query
select title, count(step_taken.step_id)as number_of_times
from step join step_taken
on step.id = step_taken.step_id
where user_id = 1 and user_id=2
group by title;
it returns nothing, but it should return some rows of step both user1 and user 2 did.
when i wrote same thing only with user_id=1 or user_id=2, it shows selected information
how can I fix my code so it can show the information I want to get?
thanks in advance :)
user_id cannot be 1 and 2 at the same time. You need a second user table. Then join those on your criteria and count:
select title, count(u1.id) + count(u2.id) as number_of_times
from step u1 join step u2
on u1.id = u2.id
where u1.user_id = 1 and u2.user_id=2
group by title;
note: cannot tell what table title is in, or the purpose of step_taken was as step.id is identical.

Database design for chatroom application

EDIT
People think this question is too broad so I'm narrowing things down a bit here:
I have a table with dual primary keys: roomID and userID.
Here is some example data:
roomID | userID
1 | 5
1 | 9
1 | 10
1 | 12
2 | 5
2 | 9
2 | 10
3 | 5
3 | 17
Given a list of users: 5,9,10, how can I return the roomID containing ONLY those users? So in this case it should return 2.
I hope this can be done within 1 SQL query.
Any help would be appreicated.
ORIGINAL QUESTION
I am making a chat room application and need to design a database backend for it. All the rooms are created on the fly and are destroyed when the last user exits the room. Users are able to add other users to any room they are in.
Currently this is my design:
I have a chatroom table with two columns. The two columns are both primary keys for the table (so a row is considered duplicate only when both columns are the same). The first column is the room ID. The second column is a user ID. The idea I have here is with the same room ID, there can be many users in this room (so rows with same room ID but different user ID). When I need to create a new room, I simply select MAX(room ID) + 1 and create a new room with this ID and add the users into it.
Given a list of users IDs (such as 1,5,31,12), I need to find out if a room is already created for them. In other words, I need to determine if there are rows all with the same room ID having users IDs 1,5,31,12. However, if a room is created with users 1,5,31,12,6 (one or more extra users), this should not count as room already created. I will then need to create a new room for them and add the users to that. Same goes for less users than the list.
Right now I'm having trouble forming the query to determine if I need to create a new room or not, and if not, retrieve the room ID of the existing room.
Any help would be appreciated.
Also, I think this design is quite cumbersome, you are welcome to suggest a better database design.
P.S. the database I'm using is MySQL
I think yoy can add 1 more col to the chatroom table, name num_member, this is number of member in room( or better have room(room_id, number_member) table). To make it simple first, I assume you have num_member in chatroom. This query might work:
Select * From chatroom where user_id IN ($userIdList) Group by room_id HAVING count(*) = chatroom.num_member
Hope this help

How can I repeat this query over several months in MySQL?

I have a membership list with over 1.2M members. People commonly subscribe, unsubscribe, and re-subscribe to the list. Often, I find myself needing to know which users were subscribed at a particular moment in time. I have a table called subscription_history, with this structure:
-----------------------------------------------------------------------
| id | native key |
-----------------------------------------------------------------------
| user_id | foreign key that joins the user table |
-----------------------------------------------------------------------
| change_code | 1 or 2 for subscriptions, 4-7 for unsubscriptions |
-----------------------------------------------------------------------
| created_at | date-time stamp when the change was made |
-----------------------------------------------------------------------
Right now, if I want to know who was subscribed at a particular date in the past (March 31, 2012 in this example), I run this query:
SELECT user_id
FROM
(SELECT
user_id
, MAX(created_at) AS last_change_date
, change_code
FROM subscriptionhistory
WHERE DATE(created_at) <= '2012-03-31'
GROUP BY user_id
) AS last
WHERE change_code IN (1,2)
This finds each user's last subscription action before or on the target date, then returns the user if that action was a subscription. We then use that list of users to run various other queries, such as the average lifetime sales. This system works well, but only for one date at a time. If I wanted to know the average subscriber's lifetime sales for every month of the year, I would have to run this query 12 times, manually incrementing the date in the WHERE statement each time.
Now I want to create a version of this that can I can use for more than a single date... so that it could give me all users subscribed in January, then February, etc., and I could run average lifetime sales for subscribers in each month. I can't just do a GROUP BY for this, since someone who was a subscriber in March might have unsubscribed in April and re-subscribed in June. I suppose I could 12 UNION queries ... but was hoping for something a little more elegant!
A few limiting parameters: I only have read-only access to the database; I cannot change anything about the table structure or make temporary tables. I have to do this only in MySQL - because of the way our CRM works, I can't use Python or PHP to manipulate results. Any help would be greatly appreciated! Please let me know if I am not explaining this well. Thanks!
SELECT user_id, group_concat(date_format(created_at, '%Y-%m')) as ActiveMonth from
(SELECT user_id, created_at, change_code from Subscriptions WHERE
change_code in (1,2) order by 1,2,3) b
group by user_id
order by user_id, ActiveMonth desc
You can take the group_concat out and the group by and it should give you a row and active month for every user_id.
I created a SQLFiddle and changed the table name to subscriptions for ease of use.
http://sqlfiddle.com/#!2/6b2f2/14

MYSQL - How to check if a user is following another user, potentially through a subselect?

I'm fetching a list of activities (activities) and using a left join to grab the user data (users) who created the activity. Within my application users have the ability to follow one another.
This is my current query, which grabs all activities not posted by yourself ($user_id)
SELECT
activities.id, activities.user_id, users.id, users.name
FROM
activities
LEFT JOIN
users on activities.user_id = users.id
WHERE
users.id != $user_id
Aside from the activities + users tables, I have a another table in my application called followers:
followers
id | user_id_1 | user_id_2 | followed_back
1 1 3 1
2 2 3 0
3 3 1 1
I need to check whether you ($user_id) have followed a particular user joined to each activity and perhaps call this new field "user_followed" which represents a true/false/null value?
For example, I'm user_id = 1. Based on the above table, this means I have followed user_id 3. When an activity is fetched and user_id 3 is joined / responsible, the new field "user_followed" would be true.
Therefore, I think I'd need to incorporate another SELECT query, checking if the user is being followed:
(SELECT
*
FROM
followers
WHERE
user_id_1 = $user_id AND user_id_2 = users.id
)
I'm just largely unsure of how to incorporate this into my initial query and create a new field representing yes or no. Any help would be much appreciated!

How to SELECT MySQL 1-to-LAST on 1-to-Many Relationship

I have 2 Tables -- Table 1 is a master file and Table 2 is an activity file.
The relationship is 1-to-Many.
I am producing a report and all I want to return is every master file row joined to only the last activity row for the related master id.
I am unsure on how to request the last activity row. My code below returns every activity row (rightfully so).
Thank you for your help.
SELECT *
FROM master_file AS master
INNER JOIN activity_file AS activity ON activity.id = master.id
ORDER BY master.display_name
The activity file has a column called entry_date. It is a date and time stamp recording every activity. I simply want to select the last entry_date.
For example:
Table 2 - Activity looks like this
ID ACTIVITY ENTRY_DATE
1 Update 2012-08-01 09:00:00
1 Edit 2012-08-01 13:45:15
3 Create 2012-07-15 10:09:52
3 Delete 2012-07-22 23:02:00
3 Add 2012-08-05 04:33:00
4 Edit 2012-08-03 15:12:00
One standard way to solve this is to create an inline view that finds the last entry_date per ID.
SELECT *
FROM master_file AS master
LEFT JOIN activity_file AS activity ON activity.id = master.id
LEFT JOIN (select id , max(entry_date) entry_date
From activity_file
group by id) last_activity
ON activity_file.id = last_activity.id
and activity_file.entry_date= last_activity.entry_date
ORDER BY master.display_name
The one problem with this approach is that you may have more than one record with max(entry_date) for a given id. You'll either need to have your business rules handle this (e.g. simply display more than one record for that case) or you'll need to figure out a tie breaker. The last thing you want is to make it non-deterministic