join two tables order by date and display results - php

I'm trying to make a function kinda similar to facebook's notification window. Their function seems to combine any kind of event and display them after date.
So i have 2 tables :
Article and comments.
both have 2 similar rows : uniquepostowner and date_posted.
I want to join them up and display them one after another.
Example :
User A has posted a comment (04.05.2012 5:30)
User B Has posted a comment (04.05.2012 6:30)
User C has written an article (04.05.2012 7:30)
user D has posted a comment (04.05.2012 8:30)
However, i'm struggling with both joining these 2 and displaying the results.
Reading others with similar scenarios ive tried this as a query:
$sesid = $_SESSION['user_id'];
$sql = "SELECT X.* FROM ( SELECT * FROM `article` WHERE uniquepostowner = {$sesid} UNION SELECT * FROM `comments` WHERE uniquepostowner = {$sesid} ) X ORDER BY X.`date_posted`";
$result = mysql_query($sql);
Then trying to fetch the results like this:
while($row = mysql_fetch_array($result))
{
echo $row['article.id'];
}
Tables:
**article**:
id
title
content
uniqueuser
date_posted
full_name
uniquepostowner
**comments**:
id
pid (same as article.id)
date_posted
content
full_name
uniquepostowner
there are more rows to these tables, but they are irrelevant.
But no success. Any help is greatly appreciated as always! :)
Currently i'm trying this, but its not doing what i want.
$sql = "SELECT * FROM article a INNER JOIN comments c WHERE a.uniquepostowner = {$sesid} AND c.uniquepostowner = {$sesid}
ORDER BY a.date_posted DESC , c.date_posted DESC ";

I think this is what you need:
UPDATED:
$sesid = $_SESSION['user_id'];
$sql = "
SELECT
X . *
FROM
(SELECT
id,
date_posted,
content,
full_name,
uniquepostowner,
'article' AS type
FROM
article
WHERE
uniquepostowner = {$sesid} UNION SELECT
id,
date_posted,
content,
full_name,
uniquepostowner,
'comment' AS type
FROM
comments
WHERE
uniquepostowner = {$sesid}) X
ORDER BY X.date_posted
";
$result = mysql_query($sql);
And you can iterate with:
while($row = mysql_fetch_array($result))
{
if($row['type']=='article'){
echo "User " . $row['full_name'] . " has written an article (".$row['date_posted'].")<br>";
} else {
echo "User " . $row['full_name'] . " has posted a comment (".$row['date_posted'].")<br>";
}
}
You can check it out at:
http://sqlfiddle.com/#!2/38778/8

you should try to rephrase your sql to only use the columns both tables have in common:
SELECT uniquepostowner,date_posted FROM `article` WHERE uniquepostowner = {$sesid}
UNION
SELECT uniquepostowner,date_posted FROM `comments` WHERE uniquepostowner = {$sesid}
ORDER BY date_posted
there are some more examples in the mysql manual.

You must make the collumns on each query of the union equal:
SELECT X.* FROM ( SELECT **uniquepostowner** FROM `article` WHERE uniquepostowner = {$sesid} UNION SELECT **uniquepostowner** FROM `comments` WHERE uniquepostowner = {$sesid} ) X ORDER BY X.`date_posted`
This is just a example, in the union, both queries must return the same amount of fields, I sugest that you return only the filds that both tables have in commom.

Maybe I'm missing the point, but wouldn't this solve the problem:
SELECT articles.*, comments.* FROM articles, comments WHERE articles.uniqueuserid = $userId AND comments.postId = articles.Id ORDER BY articles.date_published DESC
Ofc all table and field names are would need adjustments to fit with your code.
What it does, is basically it loads all articles with uniquepostowner or whatever your name is and corresponding comments sorted by publish date.
Is this what you are after?
EDIT
Actually, comments and articles are spearate, and you want to display them side by side? In that case why don't you create 'events' table, which holds the date, the owner, the type (article/comment/like/photo/anything) and id of corresponding item and use that to generate your feed?

Related

PHP MySql Query Get Sum Per User

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).

MySQL select row with and without relation

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

Php and MysQL JOIN tree table

I have one question about JOIN from PHP section .
I know this question have in stackoverflow.com but that solution is not helped me.
I am using this code for join two table:
<?php
$select_posts = "SELECT users.uid,users.user_name,user_uploads.uid_fk,user_uploads.image_path
FROM users
JOIN user_uploads
ON users.uid = user_uploads.uid_fk
WHERE user_name='$user_name' order by rand() LIMIT 0,4";
$run_posts = mysql_query($select_posts);
while($row=mysql_fetch_array($run_posts)) {
$image_path=$row['image_path'];
$uid_fk = $row['uid_fk'];
?>
This code will work but i want to add another table here.
other table name is: message
table inside have:
msg_id
uid_fk
comment_count
like_count
How can I add a third table here? Anyone can help me!
Just join the third table with an another JOIN keyword in your query.
SELECT table_users.uid,table_users.user_name,table_user_uploads.uid_fk,table_user_uploads.image_path, table_message.msg_id
FROM table_users
JOIN table_user_uploads
ON table_users.uid = table_user_uploads.uid_fk
JOIN table_message
ON table_message.uid_fk = table_users.uid
WHERE user_name='$user_name' order by rand() LIMIT 0,4

Group post by name from 2nd table php

This is litle complicated query for me, but if anyone have idea please post id...
I want to make something like this
SITE 1
post
post
post
SITE 2
post
post
post
here is my query
$result = mysql_query("SELECT content.* FROM content WHERE content.site IN
(SELECT site_id FROM site_subscription WHERE user_id = ".$_SESSION['userid'].")
ORDER by content.site DESC");
while($row = mysql_fetch_assoc($result)) {
$array[] = $row;
}
AND im display post
if(is_array($array)) {
foreach($array as $row) {
include($basepath.'/template/item.php');
}
}
This is working and post is sorted by site_id, but need to get site_name from other table, table name site and than GROUP post by site_name like above SITE 1, SITE 2, SITE 3
Something like
SELECT * FROM site WHERE id='content.site'
$result = mysql_query("SELECT content.* FROM content
INNER JOIN site ON content.site = site.id
WHERE content.site IN
(SELECT site_id FROM site_subscription WHERE user_id = ".$_SESSION['userid'].")
ORDER by content.site DESC");
Do a JOIN instead of subquery. Try something like this:
SELECT content.*, site_name, FROM content
JOIN site_subscription ON content.site = site_id
WHERE site_subscription.user_id = <USER_ID>
ORDER by content.site DESC
GROUP BY site_name
MysSQL will handle this query but it's not fully correct. You can't actually select content.* as you have to select only aggregated fields while you are grouping rows.
"SELECT * FROM content INNER JOIN site ON content.site = site.id
WHERE site.id IN (
SELECT site_id FROM site_subscription
WHERE user_id = ".$_SESSION['userid'].")
ORDER BY site.name"

PHP + MySQL: When I select from two tables, how to define from which table I want to take "id"

I have two tables, each with an "id" field. Here are the two tables:
news : id, authorid, datetime, body
authors : id, name
I have this select query:
SELECT * FROM news, authors WHERE (news.authorid = authors.id) ORDER BY news.datetime DESC;
Then, in PHP, I want to use id of the table news. I have this code:
while ($row = mysql_fetch_array($result))
{
// I want to take news.id, but it gives an error:
echo $row["news.id"]; // error: "Undefined index: news.id"
// And when I write only "id", it takes it of authors.
echo $row["id"]; // this id is authors.id, but I want news.id
}
Give them aliases
SELECT news.id AS news_id FROM news, authors WHERE (news.author = authors.id) ORDER BY news.datetime DESC;
Or
SELECT *, news.id AS news_id FROM news, authors WHERE (news.author = authors.id) ORDER BY news.datetime DESC;
IN you SQL query, you can use aliases :
select table1.id as id_1, table2.id as id_2, ...
The columns will be available from PHP using the aliases, and not the names of the columns.
In your case, you'd have :
SELECT news.id as news_id, news.authorid, news.datetime, news.body,
authors.id as author_id, authors.name
FROM news, authors
WHERE (news.author = authors.id)
ORDER BY news.datetime DESC;
And, in your PHP code, you'd use the aliases :
echo $row["news_id"];
echo $row["author_id"];
You should explicitely define the fields you want to retrieve and alias the ambigous ones:
select news.id as news_id, news.authorid, news.datetime, news.body,
authors.id as authors_id, authors.name
FROM news, authors WHERE (news.author = authors.id)
ORDER BY news.datetime DESC authors.name
user As statement in sql like
select news.id as newsid, news.authorid as newsauthorid, authors.id as authorsid ....
and in php get as
echo $row["newsid"] ;
//
echo $row["authorsid"] ;

Categories