How to fetch the linked names? - php

I have fetched the data from two different tables is this.
But now, I want the following result with their original names and not the numbers like status 1 is for Good, and user_id=1 means "Mike".

To select usernames using userID try using an inner join
And/or you can say 1 = good like so:
if($status == 1)
{
echo "Good";
}
(though this can also be done with the inner join, if you have the values in another table ofcourse)

Just JOIN your tables, something like:
SELECT f.FollowDate, s.StatusName, u.UserName
FROM Folowers f
INNER JOIN Users u ON f.UserId = u.ID
INNER JOIN Statuses s ON f.StatusID = s.ID

Related

Get all referred users in a single query?

Is it possible to get all the users that might be linked to UserID1?
For example:
UserID1 referred UserID2 and UserID5
UserID2 referred UserID3
UserID3 referred UserID4
Result on UserID1's page:
+UserID2
+UserID5
++UserID3
+++UserID4
How I am currently doing it:
$user_data['id']=1;
$primary_referral_query=mysqli_query($conn, "SELECT username FROM users WHERE referrer=$user_data[id]");
while($primary_referral=mysqli_fetch_array($primary_referral_query))
{
echo '+'.$primary_referral['username'].'<br>';
}
$secondary_referral_query=mysqli_query($conn, "SELECT a.username, b.username, c.username AS users_c_username FROM users AS a, users AS b, users AS c WHERE b.referrer = a.id AND a.id <> b.id AND c.referrer = b.id AND a.id=$user_data[id]");
while($secondary_referral=mysqli_fetch_array($secondary_referral_query))
{
echo '++'.$secondary_referral['users_c_username'].'<br>';
}
Your method of storing hierarchical data is called the adjacency list (model).
You have different options:
1) Read all data from database put it in a php array and traverse it recursively
Example: https://stackoverflow.com/a/15307555/1948627
2) Select only the current user and descendants, put it in a php array and traverse it recursively
The SQL should look like:
SELECT u1.username as lev1, u2.username as lev2, u3.username AS as lev3, u4.username AS as lev4
FROM users AS u1
LEFT JOIN users AS u2 ON u2.referrer = u1.id
LEFT JOIN users AS u3 ON u3.referrer = u2.id
LEFT JOIN users AS u4 ON u4.referrer = u3.id
WHERE u1.id = 1;
I didn't find examples for the php code, but it should be more difficult, because the data you receive is now redundant. Also note: For every new depth in the tree you have to add one JOIN in the DB select.
3) Recursive PHP/MySQL
Example: https://stackoverflow.com/a/10994181/1948627
I would go with option 1 if you don't have much data. Or better choose another way of storing or retrieving your data.
My favorite way are the Closure Tables
Another interesting opinion about Nested Sets: https://stackoverflow.com/a/31642680/1948627

How to JOIN 2 tables on mySql?

I have two tables: publick_feed and users
I want to SELECT all from public_feed and also SELECT a three columns from users whose id is the same of user_id in public_feed
and assign the rows returned from public_feed to the column in users table ( correspondent)
I try this:
<?php
$sql = "
SELECT * FROM public_feed
WHERE user_id IN
(SELECT id FROM users) AND
(SELECT Firstname,Lastname,Avatar FROM users WHERE id IN(SELECT user_id FROM public_feed))
";
$query = mysqli_query($dbc_conn,$sql);
if(mysqli_num_rows($query) > 0){
while($row = mysqli_fetch_assoc($query)){
//echo rows with correspondent details from the users table
echo $row['user_id'];
}
}
<?
Please any help will be much appreciated.
Thank you.
Or version with left join in case if there is no user in public_feed, and you still want to fetch user data
SELECT
u.*, f.*
FROM
public_feed f LEFT JOIN
users u ON f.user_id = u.id;
Because author asked for explanation, here it is:
First we are going to use table name alias to make query shorter
public_feed f
and
users u
we are saying that want to refer to tables with an alias. Of course * means that we want to select all columns
SELECT users.*, public_feed.*
is equal to
SELECT u.*, f.*
Of course you can use any other letters as an alias
Next we are saying that public_feed.user_id must be equal to users.id. But when public feed entry does not exists just display columns with null values. This is why we are using LEFT JOIN instead of INNER JOIN. In general JOINS are used to fetch related data from more than one related tables.
ON keyword is saying values from which columns in the tables must be equal to satisfy the request
I think doing a join would be cleaner than using a complicated subquery:
SELECT u.Firstname,
u.Lastname,
u.Avatar,
COALESCE(pf.User_id, 'NA'),
COALESCE(pf.Post, 'NA'),
COALESCE(pf.Date, 'NA')
FROM users u
LEFT JOIN public_feed pf
ON u.Id = pf.User_id
I chose a LEFT JOIN of users against public_feed on the assumption that every feed will have an entry in the users table, but not necessarily vice-versa. For those users who have no feed entries, NA would appear in those columns and that user would appear in only a single record.

MySQL Inner Join, selecting from multiple tables

I'm really struggling to get my head around this. I am trying to run a SELECT query from multiple tables.
This is what I have so far that doesn't work;
SELECT jira_issues.*, session_set.* FROM jira_issues, session_set
INNER JOIN reports on jira_issues.report_id = reports.id
WHERE jira_issues.report_id = 648
I have other tables (session_set, report_device) which has a ReportID and report_id column respectively.
I have a report table which has a Primary Key id. In the other tables the report.id key is linked with foreign keys.
Ultimately what I am trying to achieve is this:
I have an entry in the reports table with an id of 648. In the other tables (jira_issues, report_device, session_set), I also have entries which has a foreign key linked to the report id in the report table.
I want to run one SELECT Query to query the tables (jira_issues, report_device and session_set) and get all the data from them based on the report.id.
Thanks!
What about this:
SELECT * FROM jira_issues ji
LEFT JOIN session_set ss ON ji.report_id = ss.ReportID
LEFT JOIN report_device rd ON rd.report_id = ji.report_id
WHERE ji.report_id = 648;
Just say "no" to commas in the from clause. Always use explicit join syntax:
SELECT ji.*, session_set.*
FROM jira_issues ji inner join
reports r
on ji.report_id = r.id inner join
session_set ss
on ss.ReportId = r.report_id
WHERE ji.report_id = 648;
If some of the tables might have no corresponding rows, you might want left outer join instead of inner join.
Kindly try this out. You may get syntax error.
SELECT a., b. FROM jira_issues a, session_set b, reports c
Where a.report_id = c.id and b.report_id = c.id AND a.report_id = 648

get count of posts based on count(*)

i am trying to get number of posts that i have
Here is my query
$Query="
SELECT t.*,u.*,c.*
FROM posts as t
LEFT JOIN relations as r on r.post_id = t.post_id
LEFT JOIN users as u on t.auther_id = u.auther_id
LEFT JOIN categories as c on c.cate_id = r.cate_id
GROUP BY t.post_id
";
$Query=mysql_query($Query);
$numberOfPosts=mysql_num_rows($Query);
This query is works very well
but i am trying to convert it, i want make it faster
i want use count(*) instead of t.*
because when i use t.*, it gets the full data of posts and categories
but i want to get count only, So i decided to use count(*) but i don't know how to use it with query like this
Edit
i've replaced SELECT t.*,u.*,c.* with SELECT count(t.*)
But i got mysql Error Warning: mysql_fetch_assoc(): supplied argument
Edit 2:
i am trying SELECT count(t.post_title)
I Got this results
Array ( [count(t.post_id)] => 10 )
But i have only 2 posts!
$Query="
SELECT t.*,u.*,c.*
FROM posts as t
LEFT JOIN relations as r on r.post_id = t.post_id
LEFT JOIN users as u on t.auther_id = u.auther_id
LEFT JOIN categories as c on c.cate_id = r.cate_id
GROUP BY t.post_id
";
$Query=mysql_query($Query);
$numberOfPosts=mysql_num_rows($Query);
Let's take a step back and analyze this query for a moment.
You're selecting everything from three out of four tables used in the query. The joins create some logic to limit what you select to the proper categories, authors, etc. At the end of the day you are getting a lot of data from the database, then in PHP simply asking it how many rows were returned (mysql_num_rows). Instead, what #Dagon is trying to suggest in comments, is that you have MySQL simply count the results, and return that.
Let's refactor your query:
$query = "
SELECT COUNT(t.post_id) AS qty
FROM posts as t
LEFT JOIN relations AS r ON r.post_id = t.post_id
LEFT JOIN users AS u ON t.auther_id = u.auther_id
LEFT JOIN categories AS c ON c.cate_id = r.cate_id
GROUP BY t.post_id
";
$result = mysql_query($query);
$result_row = mysql_fetch_assoc($result);
$numberOfPosts = $result_row['qty'];
(You could also use Barattlo's custom execute_scalar function to make it more readable.)
I would need to see your table structures to be of more help on how to optimize the query and get the desired results.
try doing this:
$Query="
SELECT count(t.*) as count_all
FROM posts as t
LEFT JOIN relations as r on r.post_id = t.post_id
LEFT JOIN users as u on t.auther_id = u.auther_id
LEFT JOIN categories as c on c.cate_id = r.cate_id
GROUP BY t.post_id
";
$Query=mysql_query($Query);
$numberOfPosts=mysql_num_rows($Query);
You want to do
SELECT count(t.id) AS count FROM ....
//do query with PDO or whatever you are using
$rows = mysql_fetch_assoc();
$num_rows = $rows['count'];
You should probably simply use
SELECT count(*) as postingcount FROM posts
Why?
Because you do not have a WHERE clause, so there are no restrictions. Your JOINS do not ADD more rows to the resultset, and in the end your GROUP BY merges every duplicate occurance of a post_id that might have occurred because of joining back into one row. The result should only be counted, so assuming that the real number you want to know is the number of data sets inside the table posts, you do not need any join, and doing count(*) really is a very fast operation on tables in MySQL.
Remember to check if mysql_query returns false, because then you have to check mysql_error() and see why your query has an error.

MySQL dynamically selecting fields within join with where clause?

so I'm having trouble selecting a field only if another fields value is not equal to 0.
So, here's what's going on.
I have 3 tables, they are - users, schools, campuses
And basically, I need to select a single users data from these 3 tables. I'd like to only select the campus_name field from campuses if the users.campus_id field is not 0.
So, something pseudo coded like this might give you a better idea..
The query is being passed in a $id variable, that has some user's id.
SELECT users.*, schools.*, (if(users.campus_id != 0) then campuses.campus_name)
FROM users, schools, campuses
WHERE users.id = '$id' (if(users.campus_id != 0) then AND campuses.id = users.campus_id)
SELECT *
FROM schools,
users LEFT OUTER JOIN campuses
ON users.campus_id != 0
AND users.campus_id = campuses.id
WHERE users.school_id = schools.id
So you are joining three tables together, you always expect a user to have a school, but they may not have a campus, and if this is the case, obviously nothing should be displayed.
The best you can do is acheive this with a LEFT JOIN on campuses.
An example based on your pseudo code below:
SELECT u.*, s.*, c.campus_name
FROM users u
INNER JOIN schools s ON u.school_id = s.school_id
LEFT JOIN campuses c ON u.campus_id = c.campus_id
WHERE u.user_id = $userId
If I understood you correctly, you want ALL the information displayed, but to display campus name ONLY if it exists? If so, I believe the following statement should do the trick:
SELECT `u`.* `s`.* if(`c`.`campus_name` != 0, `c`.`campus_name`, "") as `campus`
FROM `users` as `u`
INNER JOIN `schools` as `s` ON `u`.`school_id` = `s`.`school_id`
LEFT JOIN `campuses` as `c` ON `u`.`campus_id` = `c`.`campus_id`
WHERE `u`.`user_id` = $user_id;
Untested, written from the top of my head, could be errors in there

Categories