I have users with rating and I want to show the total amount of rating of each user. I have 2 tables: users and feedback. I have 4 users in USERS table. And in table FEEDBACK (consists of applicant_id and app_experience columns) I have the rating of each user. But, I have several ratings for each person.
$sql4 = "
SELECT SUM(app_experience) as app_experience
, applicant_id
FROM feedback f
JOIN users u
ON u.id=f.applicant_id
GROUP
BY feedback.applicant_id
";
$res4 = mysqli_query($db,$sql4) or die(mysqli_error($db));
This is my output, but it prints only 2 users, because in table FEEDBACK 2 of the users do not have any feedback yet:
foreach ($res4 as $row)
{
echo "".$row['applicant_id']."----".$row['app_experience']."";
echo "<br>";
}
My question is how to output all 4 users and I want to show the total number of rating next to each user.
I am doing something like this, but I do not know where to add the foreach loop above in the code below. Do you have any ideas?:
$sql2 = "SELECT * FROM users";
$res2 = mysqli_query($db,$sql2) or die(mysqli_error($db));
while($row2 = mysqli_fetch_assoc($res2))
{
$id = $row2['id'];
$name = $row2['name'];
}
You just have to modify the below statement :
$sql4 = "SELECT SUM(app_experience) as app_experience, applicant_id FROM feedback INNER JOIN users ON users.id=feedback.applicant_id GROUP BY feedback.applicant_id";
to :
$sql4 = "SELECT COALESCE(SUM(app_experience), 0) as app_experience, applicant_id FROM users LEFT JOIN feedback ON users.id=feedback.applicant_id GROUP BY users.id";
The users LEFT JOIN feedback ... clause will allow the query to return a row even for users who do not have a feedback yet.
The COALESCE(SUM(app_experience), 0) will evaluate to 0 when a user has no feedback yet.
With this solution you don't need to loop.
SELECT users.*, (SELECT SUM(app_experience) FROM feedback WHERE applicant_id = users.id) as feedback FROM users
Selects all users and their feedback in a short SQL
As written, your query will not run. The GROUP BY clause is referencing feedback, but that reference has been changed to f by the alias.
You appear to want a LEFT JOIN:
SELECT u.id, SUM(f.app_experience) as app_experience
FROM feedback f LEFT JOIN
users u
ON u.id = f.applicant_id
GROUP BY u.id;
This will return a NULL value for app_experience. If you want a value (such as 0) use COALESCE(SUM(f.app_experience), 0).
Related
Here is database table:
$sql[2] = "SELECT u.* , oi.* , COUNT(oi.user_id) AS count
FROM users u, order_items oi
WHERE u.id=oi.user_id ";
$result3= mysqli_query($conn,$sql[2]) or die(mysqli_error());
if (mysqli_num_rows($result3) > 0) {
while ($record = mysqli_fetch_array($result3)) {
echo $record['count'];
}
}
I want to count how much order have every user. Example: Like Thomas have 3 order, but my code is writing 4, i want to write Thomas (3), Gracian(1). Any idea how to fix it ?
Use this query:
SELECT u.id,
COUNT(oi.user_id) AS orderCount
FROM users u
LEFT JOIN order_items oi
ON u.id = oi.user_id
GROUP BY u.id
The reason we count user_id from the order_items table is because of the edge case where a given user has no orders. In this case, we want to make sure that his count would appear as zero. The COUNT function ignores NULLs, which is what we want.
There is another way to perform the sql query using subqueries:
SELECT id,
email,
address,
name,
(SELECT count(user_id) FROM order_items WHERE user_id = users.id) AS orderCount FROM users;
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.
Let say I have 2 mysql tables 'movies' and 'seen'
If a user already saw a movie there is a record in the 'seen' table, with his userID and the movieID
I have to print ALL the movies, and then if the user already saw the movie print "already watched" otherwise "to watch".
At this time I use PHP with 2 seprate queries:
<?php
$res = mysql_query( "SELECT * FROM movies" );
while( $row = mysql_fetch_assoc( $res ) ) {
echo $row['movie_name'];
$res2 = mysql_query( "SELECT * FROM seen WHERE userID = '$uid' AND movieID = '$row[id]' LIMIT 1" );
if( mysql_num_rows( $res2 ) == 1 ) { echo "already watched"; } else { echo "to watch"; }
}
There is a way to do that with ONE single query?
With JOIN on "movies.id = seen.movieID" it only print the wahtched movies, with "WHERE movies.id NOT IN ( SELECT seen.movieID FROM seen WHERE seen.userID = '$uid' )" it only print the not watched..
In this cases you can use from LEFT JOIN, in the left join you can see data which is on table first and is not on second table.
SELECT * FROM movies LEFT JOIN seen ON movies.id = seen.movieID
if data of seen table was on result data exist if not user did not seen.
Also you can use UNION in your solution and merge to query
You can create a sub query which aggregates the number of times a user has seen a movie:
SELECT m.userid, m.movieid,
case when s.seencount is null then 0 else 1 end as seenmovie
FROM movies m left join
(SELECT movieid, userid, count (id)
FROM seen
GROUP BY movieid, userid) as s on m.movieid = s.movieid and m.userid = s.userid
This will also handle cases where users have watched a movie more than once
I'm on a mobile device so apologies if any typos but you should get the idea
SELECT * FROM `movies`
LEFT JOIN ( select movieName,'Watched' as w from seen where userId='$uid' ) s
on s.movieId=movies.movieId
Will give watched when movie is watched otherwise it will give NULL
I want to compare mysql id between 2 table and display all name with match id echo yes.
I have 2 table one is wine and the other is user. I will use unique id column from table wine. But in table user, I will use wine_id column which are not unique.
This is mysql code that will get a matching id from table wine and user.
$sql="SELECT id FROM `winelist` w WHERE page = 'Chardonnay USA' and
EXISTS(
SELECT wine_id FROM `user_wine_history` u WHERE user_name = 'bon'
AND u.wine_id = w.id);";
$result= mysql_query($sql);
while($data= mysql_fetch_array($result)) {
}
and this is the code for for listing all the name in wine.
$sql2 ="SELECT id, name, year, grape, price, instock FROM winelist WHERE page ='Chardonnay USA';";
$result2 = mysql_query($sql2);
while($data2 = mysql_fetch_array($result2)) {
}
I tried to use this code in listing name while loop but it didn't work.
if($data2['id'] == $data['id']) {
echo "yes";
}
else
{
echo "fail";
}
Can anybody give me some advice how to solve this?
Thank you in advance.
You can use LEFT JOIN instead and do this within the query using the CASE expression, something like:
SELECT
w.id , w.page, w.name, w.year,
u.user_name, u.id user_id, u.wine_id uwine_id,
CASE
WHEN u.id IS NOT NULL THEN 'Yes'
ELSE 'No'
END AS IsMatching
FROM `winelist` w
LEFT JOIN `user_wine_history` u ON w.id = u.wine_id
AND w.page = 'Chardonnay USA'
AND u.user_name = 'bon';
This will select a new column IsMatching with values yes or no to indicate whether the wine id is found in the other table or not.
SQL Fiddle Demo
Use Join:
$id= Here the input
SELECT id FROM `winelist` w
INNER JOIN `user_wine_history` u
ON u.wine_id = w.id
WHERE w.page = 'Chardonnay USA' AND u.user_name = 'bon'
AND w.id = '".$id."'
I'm trying to accomplish:
selecting top 20 highest score users with the least SQL / PHP way possible.
caching is still not been considered for now.
What I've done so far:
I'm able to retrieve all 5k+ records with their scores, but not able to limit to only retrieve or calculate top 20(example).
Tables:
users (id, name)
score_rec (id, uid, points) This table has multiple entries for each user. Highest scores will be the ones which has highest amounts of rows, entries. Example: UID 23 could have 5 rows which belong to it, his score is 5.
Code Sample:
$query = "SELECT * FROM score_rec,users where users.id = score_rec.uid";
$result = mysql_query($query);
$array1 = Array();
while($row = mysql_fetch_array($result) )
{
//Count their scores
$query2 = "SELECT users.id,users.name,score_rec.uid FROM `score_rec`,`users` where score_rec.uid = $row[uid] and users.id = $row[uid]";
$result2 = mysql_query($query2);
$scores_count = mysql_num_rows($result2);
$array1["$row[name]"] = $scores_count;
}
I'm thinking this might be possible with maybe a temporary table script, stored procedure, or simple query which could look at both tables. Since scores_rec could be used by itself to calculate higuest entries holders, maybe one query could suffice to both tables.
Thank you all for any direction given.
What about something like this :
select users.id, count(*) as score
from users
inner join score_rec on users.id = score_rec.uid
group by users.id
order by count(*) desc
limit 20
This will :
For each user, count how many rows he has (because of the group by)
sort all users by number of rows -- in descending order
keep the first 20 resulting rows -- which are the 20 users who have the bigger number of rows
$query = "
SELECT users.id,users.name,count(*) score
FROM score_rec
INNER JOIN users on users.id = score_rec.uid
GROUP BY users.id,users.name
ORDER BY score DESC
LIMIT 20
";
$result = mysql_query($query);
$array1 = Array();
while($row = mysql_fetch_array($result) )
{
$array1["$row[name]"] = $row['score'];
}
Depending on how you want your scores:
1) global top 20 scores, possibly repeating users:
SELECT users.id, users.name, score_rec.points
FROM users
LEFT JOIN score_rec ON users.id = score_rec.uid
ORDER BY score_rec.points DESC;
2) scores of the top 20 distinct players:
SELECT DISTINCT users.id, ...
etc...