How to put logic into SQL? - mysql

First at all i am sorry for asking silly question like this.
I am new into sql. Leaned basic things from internet but cant figure this out.
Lets think i have a table named post where i store peoples post. Table structure is like this..
Post_id | poster_id | text
1 | 12 | "hello this is a post"
2 | 15 | "Another post"
3 | 77 | "More counting"
There is a table named "Friends" Where i store whos friend is who. Table structure is like this..
user_one | user_two
1 | 88
84 | 33
1 | 66
Now i can use SQL like this to get post from post
SELECT * FROM POST INNER JOIN frnends ON user_one = poster_id WHERE 1
But this will get a table by joining two table together, Cant i do some logic like this?
SELECT post FROM post WHERE poster_id = (SELECT user_two,user_one FROM friends WHERE user_one = MY_id OR user_two = MY_id
perhaps MY_id is a variable WHERE MY_id = 1
Now to do this kind of logic?
Any help will be so great.

Sorry, I lack the reputation to comment. Gamal's solution should be refined to prevent the return of My_id's posts;
SELECT *
FROM post p
INNER JOIN friends AS f on p.poster_id IN (f.user_one, f.user_two)
WHERE My_id IN (f.user_one, f.user_two)
AND p.poster<>My_id;
Or if you do want those posts as well;
SELECT *
FROM post p
INNER JOIN friends AS f on p.poster_id IN (f.user_one, f.user_two)
WHERE My_id IN (f.user_one, f.user_two)
AND p.poster<>My_id
UNION
SELECT *, My_id AS user_one, NULL AS user_two
FROM post p
WHERE p.poster=My_id;
The problem is that Gamals suggestion will return each post by My_id once for every relation that My_id is part of.

try this:
SELECT *
FROM [sample].[dbo].[posts] a inner join [sample].[dbo].[friends1] b on a.posterId=b.user_one or a.posterId=b.user_two where a.PosterId=12

Related

Selecting 2 rows from same table for different criterias

I've tried many examples for inner joins, outer joins and even tried conjuring my own with guesses (which more than often works) but no luck here.
TABLE 1:
follower_user_id, followed_user_id
(note it's followeR_ and followeD_)
TABLE 2:
user_id, username
So I need two rows from TABLE 2 where one user_id matches follower_user_id and another row where user_id matches followed_user_id
Query within query works but I know this isn't the way to go...
SELECT f.*, u.*
FROM tbl_follows f, tbl_users u
WHERE follower_user_id = u.user_id
That's the basic query
while($row = $r->fetch_assoc()){
//here i make another query to get the username of the followed_user_id
}
Surely this can be done in a single query?
Thanks in advance
--- UPDATE 1: Sample Data ---
tbl_users
user_id | username
--------------------------------------
1 | abc123
2 | xyz789
3 | nosey123
tbl_follows
follower_user_id | followed_user_id
-------------------------------------------
3 | 2 //nosey123 is following xyz789
3 | 1 //nosey123 is following abc123
1 | 2 //abc123 is following xyz789
While Results :
echo "$row[username] is following $row['???????']<br />"
I'm looking for:
nosey123 is following xyz789
nosey123 is following abc123
abc123 is following xyz789
Have you tried something like this?
SELECT f.*, u.*
FROM tbl_follow f
JOIN tbl_users u ON u.user_id = f.follower_user_id OR u.user_id = f.followed_user_id;
This should return two rows for each userID, since there will be one match for follower user and one match for followed user.
SELECT DISTINCT(A.user_id), A.username, B.*
FROM tbl_follow A
JOIN tbl_users B
ON B.user_id = A.follower_user_id
OR B.user_id = A.followed_user_id;

get friends of friend using mysql

I am making a query in which i want to get friends of friends but the problem is that if my friends are also friends it suggesting their ids too . Suppose user id is 1 and he has teo friends 2 and 3 and 2 has is friends with 4 and 3 and 3 is friends with 5 and 2 then its suggesting me 4,5 which it should but also suggesting 2,3 because they are friends and they both are also my friends which is wrong it should only suggest 4,5
My query is
SELECT fr.friend_id
FROM friend_list fl ,friend_list fr
WHERE fl.login_id='27'
AND fl.status='3'
AND fl.friend_id=fr.login_id
AND fr.status='3'
AND fl.login_id!=fr.friend_id
One way to do this is to add WHERE NOT IN predicate :
SELECT fr.friend_id
FROM friend_list fl
INNER JOIN friend_list fr ON fl.friend_id = fr.login_id
AND fl.status = fr.status
WHERE fl.login_id = 27 AND fl.status = '3'
AND fr.friend_id NOT IN(SELECT friend_id
FROM friend_list
WHERE login_id = 27 AND friend_id IS NOT NULL)
The subquery after the NOT IN will select the friends of the friend id you are passing. to exclude them.
SQL Fiddle Demo
This will give you only 4, 5 for the example you gave in your question:
| FRIEND_ID |
|-----------|
| 4 |
| 5 |
Note that: I used the explicit JOIN syntax instead of the old JOIN syntax you are using, it should be the same but it is recommended to use the new one.

Get all the friends of friends list

I have a table "friendship" like this
user_id
friend_id
For each friendship I make one record instead of two.
---------------------
user_id | friend_id |
--------------------
1 | 2 |
--------------------
And I Don't add (2 , 1) into table.
So, I need to get all the friends of friends list including those who are already in my friend list preferably without subqueries. Any suggestions ?
Thanks :)
Are you looking for something like this?
SELECT f2.friend_id
FROM friendship f1 JOIN friendship f2
ON f1.friend_id = f2.user_id
WHERE f1.user_id = 1
Here is SQLFiddle demo

MySQL select distinct across multiple tables

I have a query that selects all columns from multiple tables, but it's returning multiples of the same values (I only want distinct values).
How can I incorporate something like this? When I try this, it still
Select Distinct A.*, B.*, C.*....
Does distinct only work when selecting the column names and not all (*) ? In this reference it says distinct in reference to column names, not across all of the tables. Is there any way that I can do this?
edit - I added more info below
Sorry guys, I just got back onto my computer. Also, I just realized that my query itself is the issue, and Distinct has nothing to do with it.
So, the overall goal of my Query is to do the following
Generate a list of friends that a user has
Go through the friends and check their activities (posting, adding friends, etc..)
Display a list of friends and their activities sorted by date (I guess like a facebook wall kind of deal).
Here are my tables
update_id | update | userid | timestamp //updates table
post_id | post | userid | timestamp //posts table
user_1 | user_2 | status | timestamp //friends table
Here is my query
SELECT U.* , P.* ,F.* FROM posts AS P
JOIN updates AS U ON P.userid = U.userid
JOIN friends AS F ON P.userid = F.user_2 or F.user_1
WHERE P.userid IN (
select user_1 from friends where user_2 = '1'
union
select user_2 from friends where user_1 = '1'
union
select userid from org_members where org_id = '1'
union
select org_id from org_members where userid = '1'
)
ORDER BY P.timestamp, U.timestamp, F.timestamp limit 30
The issue I'm having with this (that I thought was related to distinct), is that if values are found to meet the requirements in, say table Friends, a value for the Posts table will appear too. This means when I'm displaying the output of the SQL statement, it appears as if the Posts value is shown multiple times, when the actual values I'm looking for are also displayed
The output will appear something like this (notice difference between post value in the rows)
update_id | update | userid | timestamp | post_id | post | userid | timestamp | user_1 | user_2 | status | timestamp
1 | update1 | 1 | 02/01/2013 | 1 | post1| 1 | 2/02/2013| 1 | 2 | 1 | 01/30/2013
1 | update1 | 1 | 02/01/2013 | 2 | post2| 1 | 2/03/2013| 1 | 2 | 1 | 01/30/2013
So, as you can see, I thought I was having a distinct issue (because update1 appeared both times), but the query actually just selects all the values regardless. I get the results I'm looking for in the Post table, but all the other values are returned. So, when I display the table in PHP/HTML, the Post value will display, but I also get duplicates of the updates (just for this example)
When you select distinct *, you select every row, including the one that makes the record unique. If you want something better than what you are getting, you have to type the individual column names in your select clause.
It would be easy if you explain a little more what is the connection between the tables you'r querying, because you can use joins, unions (as mentioned above) or even group by's ...
Your updated post shows one of the JOIN conditions as:
JOIN friends AS F ON P.userid = F.user_2 OR F.user_1
This is equivalent to:
JOIN friends AS F ON (P.userid = F.user_2 OR F.user_1 != 0)
and will include many rows that you did not intend to include.
You probably intended:
JOIN friends AS F ON (P.userid = F.user_2 OR P.userid = F.user_1)
I think you want this:
select *
from tableA
union
select *
from tableB
union
select *
from tableC
This assumes that HHS tables all have the same number of columns and they are of the same data type. This not, you'll have to select specific columns to make it so.

two way joins mysql query

message table
id user_id| message
1 1 | this is my cruel message
2 1 | this is my happy message
3 2 | this is happy messgae
message_tags table
id message_id| tags
1 2 | happy
2 3 | happy
what i want to acess all the messages that have the the tag happy, how would construct the query in the best possible way :)) thanks
p.s. this is just an example database
select m.id, m.user_id, m.message,
u.Username
from message m
inner join user_table u on m.user_id = u.id
where m.id in (select message_id from message_tags where tags = 'happy')