Count user actions using two different MySQL tables - mysql

I have two tables; users and texts.
users keeps the user information, such as username, password, etc.
texts keeps some texts and some additional columns like added_from, updated_from, deleted_from so when a user makes a specific action, his username is written in the texts record in related column (if I update the text my username is written in updated_from column).
I want to count all user actions according to columns added_from, updated_from, deleted_from and the result has to be something like
Username | Added | Updated | Deleted
========|=======|=========|======
user_1 | 1 | 9 | 0
user_2 | 5 | 9 | 2
The query i'm trying to use is
SELECT t.added_from,
COUNT(t.added_from) AS Added,
COUNT(t.updated_from) AS Updated
FROM users u, texts t
WHERE u.username = t.added_from
GROUP BY u.username ORDER BY u.id ASC
but it shows results only for the first username that finds in texts.
I want to print all usernames from users table and count all their actions depending on how many times their username is shown in columns added, updated or deleted

I think that you want conditional aggregation. The logic should look like:
select
u.username,
sum(u.username = t.added_from) added,
sum(u.username = t.updated_from) updated,
sum(u.username = t.deleted_from) deleted
from users u
inner join texts t
on u.username in (t.added_from, t.updated_from, t.deleted_from)
group by u.username

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.

Mysql select IN another table row for each returned result

I have two tables section and users. I need to run a simple query to return all sections. However for each section there MAY be a corresponding id in a field with multiple ids in the users section. ie ids = 2,6,8,10
Here is an example for selecting a specific section by id and its assigned users.
Select * from section, users where sectionid = '2' and sectionid IN (`ids`);
This would return all the user.ids where 2 is within ids
My problem is I need to select all of the users assigned to each section in one table?
section
------------------------------------
sectionid, sectionname, Description
2 section2
4 section4
6 section6
8 section8
User
------------------------------------
userid, ids(of the section/s),
1 4,6
2 4,8
3
4 4,6,8
Desired result: Display ALL sections whether or not users are assigned to and in one column display the userid/s assignes to each section as below.
Result
-------------------
Sectionid, sectionname, usersassignedtothissection
2 section2 null (no one assigned to section2)
4 section4 1,2,4
6 section6 1
8 section8 2,4
You can use the following solution, using FIND_IN_SET to JOIN the tables:
SELECT
section.sectionid,
section.sectionname,
GROUP_CONCAT(user.userid ORDER BY user.userid) AS 'usersassignedtothissection'
FROM section
LEFT JOIN user ON FIND_IN_SET(section.sectionid, user.ids)
GROUP BY section.sectionid, section.sectionname
demo: http://sqlfiddle.com/#!9/f9b860/5/0
Note: It is not recommended to use a column to store multiple values! You can create a mapping table to map the table section to table user like the following:
CREATE TABLE section_user (
user_id INT,
section_id INT
)
In this case your query would be the following:
SELECT
s.sectionid,
s.sectionname,
GROUP_CONCAT(u.userid ORDER BY u.userid) AS 'usersassignedtothissection'
FROM section s
LEFT JOIN section_user su ON s.sectionid = su.section_id
LEFT JOIN user u ON su.user_id = u.userid
GROUP BY s.sectionid, s.sectionname
demo: http://sqlfiddle.com/#!9/432059/2/0

Compare 2 fields of table A with 6 fields of table B

I've got two tables in my MySQL DB. One contains requiredSkill1, requiredSkillLevel1, requiredSkill2, requiredSkillLevel2, requiredSkill3 and requiredSkillLevel3.
The other table has X rows per user with the following collumns: skill and level.
itemid requiredSkill1 requiredSkillLevel1 requiredSkill2 requiredSkillLevel2 requiredSkill3 requiredSkillLevel3
2410 3319 4 20211 1 NULL NULL
The other table:
userid skill level
21058 3412 4
21058 3435 2
21058 3312 4
Keep in mind, these are just examples.
I want every itemid which has matching values in requiredSkill{1-3} and requiredSkillLevel{1-3}.
Is this even possible with a single query and is this still performant, since the user table contains up to 300 rows per user and the item table has a fixed value of 6000 rows. This will be used in a web application, so I can use Ajax to load ranges of items from the database to decrease loading time.
I don't have the data set up. A SQL Fiddle would be helpful, but I think you want to approach it like this:
SELECT itemid FROM items i
INNER JOIN users u1 ON u1.skill = i.requiredSkill1 AND u1.level >= i.requiredSkillLevel1
INNER JOIN users u2 ON u2.skill = i.requiredSkill2 AND u2.level >= i.requiredSkillLevel2 AND u1.userid = u2.userid
INNER JOIN users u3 ON u3.skill = i.requiredSkill3 AND u3.level >= i.requiredSkillLevel3 AND u3.userid = u1.userid
Someone will solve this for you if you post demo data.

selecting all rows where a column has an specific ID

So I have a badly designed database (I think) which I can't change. It's a twitter like app where the users can follow each other. Every user has it`s row in the table, and in that table there is a column named 'following' which represents all USERID's that a user is following. In that column there is a list of USERID's separated with a coma. So lets say the user with the ID 1 is following users 2 and 3 and the user with ID 2 is following user 1 the table would look like this, user 3 is not following anybody.
USERID | username | following
-------------------------------------------
1 | some user | 2,3
2 | test1 | 1
3 | test2 |
Question is how do I show all the users which user 1 is following?
EDIT 1
The code that did not work from 491243, posting here, maybe I missed something in php
$USERID = $_GET['userid'];//this has a value, so not the problem here
$sql_select = "SELECT B.USERID FROM users A INNER JOIN users B ON FIND_IN_SET(B.USERID, B.following) > 0 WHERE B.USERID = '$USERID'";
$result_select = mysqli_query($link,$sql_select);
while($record = mysqli_fetch_array($result_select))
{
$following = $record['USERID'];
var_dump($following); //result is nothing, not even NULL
}
EDIT 2
Just for sanity check I did this:
$sql_select = "SELECT USERID FROM users WHERE USERID = '1'";
$result_select = mysqli_query($link,$sql_select);
while($record = mysqli_fetch_array($result_select))
{
$following = $record['USERID'];
var_dump($following); //result is 1, like it`s supposed to be
}
Is it possible my PHP code is wrong for the query in the replays?
Your table schema is in bad shape. you should normalize it properly. But to answer you question, you can still get the result you want using JOIN and FIND_IN_SET
SELECT b.userid, b.username
FROM tableName a
INNER JOIN tableName b
ON FIND_IN_SET(b.userID, a.following) > 0
WHERE a.userID = 1
SQLFiddle Demo
My preferred design would be
User Table
UserID (PK)
UserName
Following Table
UserID (FK) - also a PK with FollowID
FollowID (FK)
You might be looking for FIND_IN_SET()
SELECT userid, username
FROM tableName
WHERE FIND_IN_SET('1', following);
SAMPLE FIDDLE

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!