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
Related
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
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
I want to find if a conversation between one user and others exists and from there select only the name of the other participant(s) (in this case, the user(s) that is/are not authenticated, that have chatted with authenticated user).
So, lets say that user 1 has chatted with user 5 and 6, how do I find the users user 1 has had a conversation with, regardless of whether he started it or the others did? The messaging table would look something like this
Columns: | id | fromId | toId | msg |
0 1 5 'hi'
1 5 1 '..'
3 1 6 '!'
4 6 1 '?'
5 1 5 '#'
I wound only need the name of each user once, so the query for this should result in (for user 1):
5, 6
I have this so far:
SELECT * FROM `messaging`
INNER JOIN (SELECT * FROM messaging
WHERE `toId` = 1
ORDER BY id DESC) a
on (messaging.id=a.id)
GROUP BY messaging.fromUser;
But of course, this only returns a result if the other user sent a message to the authenticated user, and not vice versa. How can I add the other scenario to this query? So that it also finds the conversations where fromId = 1 and fetches toId?
I realize I probably couldn't explain this very well, but I hope it's clear. My native language is not english and I suck a mySQL.
Thank you.
This should solve what you're trying to do:
SELECT fromId AS userId FROM messaging
WHERE toId = 1
UNION
Select toId AS userId FROM messaging
WHERE fromId = 1;
I have a doubt where trying to join two tables by a previous search. I've looked several solutions and read some chapters in a mysql book but I think I'm pretty close to the right answer but still not get it
I have this table "userprocess":
idProcess username state
------------------------------------------
1 blisssing 3
2 enriquecalvera 1
2 africabaluja 2
1 enriquecalvera 3
2 blisssing 1
The primery key for this table is the union of idProceso+username.
I have this other table "user":
index username pass active tipeUser .... so on
----------------------------------------------------------------- ----
1 blisssing 6OiZVVUPi3LDE 1 user
2 carmen 6OOtfrXB2Nu5. 1 user
3 consuelo 6OgdhVSkr1VDs 1 user
4 africabaluja 6OoPtGjWMQARE 1 user
5 enriquecalvera 6O6tvHg.122uQ 1 user
The thing is I want to show the join of the two tables but with a search within the first table. If I run this query
SELECT username FROM userprocess where idProcess='1' ORDER BY state
I get this:
username
---------
blisssing
enriquecalvera
which is what I am looking for, but I want to show all the fields in the "user" table for those usernames ordered by idProceso. So I run this other query:
SELECT *
FROM
user u,
userprocess p
WHERE
u.username=p.username
AND u.username IN (
SELECT username
FROM userprocess
where idProcess='1'
ORDER BY username
) ORDER BY p.state
I got this:
username pass active tipeUser idProcess state
----------------------------------------------------------------------
blisssing 6Od3nSkfOiwlg 1 user 2 1
enriquecalvera 6Oc9usiDEk51U 1 user 2 1
enriquecalvera 6Oc9usiDEk51U 1 user 1 3
blisssing 6Od3nSkfOiwlg 1 user 2 3
But this is not what I want I just want the same two results as in the previous query but with all the columns of the result of joining the two tables..
I know there is a lot of questions like this, but I have tried a lot of things and still not having the desire result..
What am I missing?
thank you, if you have any qestion or doubt just ask :)
The reason you're seeing multiple results is because you're joining on just the username, but of course the userprocess table has 2 rows where username = enriquecalvera. Your subquery is correctly only returning the 1 row you're interested in (where idprocess = 1) but as your join is seperate to this, and therefore doesn't include the idprocess = 1 condition, you're getting both rows back.
You should just do this in one step with a join like this:
SELECT *
FROM
user u
INNER JOIN userprocess p on u.username=p.username and p.idProcess='1'
ORDER BY p.state
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!