I have a forum where users can post questions and can comment and tweet.
I want to get all the comments and tweets of each post.
What i did previously was do that in 3 sets queries.
$data = mysqli_query($con,"select * from posts");
while($row = mysqli_fetch_assoc($data)){
$pid = $row['post_id'];
$dataCo = mysqli_query("SELECT comments.* FROM comments WHERE post_id = $pid");
$dataTw = mysqli_query("SELECT tweets.* FROM tweets WHERE post_id = $pid");
//2 while loop for comments and tweets
}
Can anyone show me how can i do these things in one single query because if a get a lot of posts in 1st query then there will be lots of queries to do.
OR
Maybe there is a faster way to do ?
Maybe you can use Mysql IN clause
http://www.tutorialspoint.com/mysql/mysql-in-clause.htm
In your example you have always 2*n + 1 queries to DB. Where n in number of returned rows in this query
$data = mysqli_query($con,"select * from posts");
If you use mysql IN Clause you will have only 3 queries.
Your queries should looks like
$dataCo = mysqli_query("SELECT comments.* FROM comments WHERE post_id IN (1,2,3,4)");
$dataTw = mysqli_query("SELECT tweets.* FROM tweets WHERE post_id IN (1,2,3,4)");
Numbers "1,2,3,4" are post_id returned in your first question.
Related
Here's my usual way of counting rows...
$query = "SELECT * FROM users";
$stmt = $db->prepare($query);
$stmt->execute();
$count = $stmt->rowCount();
This will count all rows, even if I use a WHERE clause, it'll still count every row that meets that condition. However, let's say I have a table, we'll call it tokensEarned (that's my actual table name). I have the following data...
user_id = 1,2,4,5,8,8,2,4,3,7,6,2 (those are actual rows in my table - clearly, user 1 has 1 entry, 2 has three entries, etc.) In all, I have 12 entries. But I don't want my query to count 12. I want my query to count each user_id one time. In this example, my count should display 8.
Any help on this? I can further explain if you have any specific questions or clarification you need. I would appreciate it. Thank You.
The following query will yield the distinct user count:
$query = "SELECT COUNT(DISTINCT user_id) AS cnt FROM users";
$stmt = $db->prepare($query);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo "distinct user count: " . $row['cnt'];
It isn't possible to get all records and the distinct count in a single query.
Whether you use the query above or you return all the actual distinct rows really depends on whether you need the full records. If all you need are the counts, then it is wasteful to return the data in the records, and what I gave above is probably the best option. If you do need the data, then selecting all distinct rows might make more sense.
You can use distinct in mysql to select only unique fields in your table.
$query = "SELECT distinct user_id FROM users";
$stmt = $db->prepare($query);
$stmt->execute();
$count = $stmt->rowCount();
Change your query to the following, this way you only shows the unique user_id:
$query = "SELECT DISTINCT user_id FROM users";
How can I get a row's info from another table without having to SELECT each loop?
//get posts from "posts" table
$stmt = $dbh->prepare("SELECT * FROM posts WHERE user_id = :user_id");
$stmt->bindParam(':user_id', $userId);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $row) {
echo $row['post'];
//get poster's full name from "users" table
$stmt = $dbh->prepare("SELECT * FROM users WHERE user_id = :user_id");
$stmt->bindParam(':user_id', $row['poster_id']);
$stmt->execute();
$result2 = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($result2 as $row2) {
echo $row2['full_name'];
}
}
how can I make this code more efficient and faster?
imagine if i have 1000 posts and each is posted by a different user. i need to get the full name of that user that posted the post. right now, i need to SELECT 1000 times because of those 1000 users. it seems so inefficient right now. how can i make it better?
I heard join might work? what are the solutions?
SELECT * FROM posts
JOIN users ON posts.user_id = users.id
WHERE posts.user_id = :user_id.
You are right, joining the users table onto your posts query will be faster.
Something else you can do to increase performance is to cache the results of your query in something like memcache and then clear the cache when a post is added or deleted. That way you don't need to hit your db every time this data is needed.
how would i go about ordering by a value that is not in the table where i am selecting from, in this instance the value $count1 is not in the table search.
count has the same identifying id as that of the thing it is being reffered to in the other table, this is where count1 is grabbed
$q = $db->prepare("SELECT COUNT(rating) FROM ratings WHERE id='$id' AND rating = 'd'");
$q->execute();
$count1 = $q->fetchColumn();
$query = "SELECT * FROM search WHERE title LIKE '$each' ORDER BY '$count1'"
$query = $db->prepare($query);
$query->execute();
that is from ratings, how would i go about ordering the entries like that, so that they are based off the number of count1 and are decided, i might have to implement something like
$query = "SELECT * FROM search WHERE title LIKE '$each' AND id = '$id' ORDER BY '$count1'"
$query = $db->prepare($query);
$query->execute();
Possible Duplicate: Mysql order by specific ID values
Same thing here, you'll just output your $count1as a comma separated string and add it in the SQL query as ORDER BY FIELD(COUNT,___comma_sep_string___)
ratings is a table, not a database. You can join tables or use subqueries to get the desired result, without having to make multiple queries.
You haven't described how the FOREIGN_KEY is set up in the ratings table, but assuming you have something ratings.search_id, this should work:
SELECT search.*, (SELECT COUNT(rating)
FROM ratings
WHERE ratings.search_id = search.id
AND rating = 'd'
) AS rating_count
FROM search
WHERE title LIKE '$each'
ORDER BY rating_count
I want to echo data from two tables to one variable. Here is the code that I have so far:
$sqlCommand = "SELECT * FROM News ORDER BY id DESC LIMIT 10";
$sqlCommand3 = "SELECT * FROM Users ORDER BY id";
$query = mysql_query($sqlCommand) or die(mysql_error());
$query3 = mysql_query($sqlCommand3) or die(mysql_error());
$count = mysql_num_rows($query);
if($count > 1) {
$News .= "";
// How do I add the query3 here?? along side the already existing one
while($row = mysql_fetch_array($query)) {
// some of the $row here are from query one and some are from query 3
$News .= "<div class=\"news-post\"> <img src=\"".$row['author']."\"><p>".$row['author']."</p> <h2>".$row['title']."</h2></div>";
} // close while
This isn't the right way to go about it, instead try using a SQL join. In this case, you'll want a unique FULL OUTER JOIN.
SELECT * FROM News
FULL OUTER JOIN USERS
ON News.id = Users.id
WHERE News.id IS NULL
OR Users.id IS NULL;
This should give you all rows containing all columns from both tables. Depending on the actual relationship, you may want some different kind of join (refer to previous link)..but this seems like what you were trying to accomplish in your example.
Warning: you are using the mysql_* extension which has been deprecated in PHP 5.5. Please use either mysqli_* or PDO.
Your User table should be linked to the News table by a oneToMany association.
So a user writes a news and a new is written by a user.
And you need to add a join in your SQL query.
$sql = 'SELECT u.username, n.* FROM News n JOIN User u ON n.user_id = u.id';
Then, you while only have to execute one SQL statement and display the result in you HTML.
Have look to this website.
I have the following query:
$select = mysql_query("SELECT * FROM posts WHERE id = $postIds");
while ($return = mysql_fetch_assoc($select)) {
$postUrl = $return['url'];
$postTitle = $return['title'];
echo "<h1><a href='$postUrl'>".$postTitle."</a></h1>";
}
Now the problem is, the variable $postIds often times contain the same id multiple times. So the title of the post echos itself multiple times. Is there a way to have it echo only once?
Use DISTINCT in your query: SELECT DISTINCT url, title FROM posts WHERE id =
http://php.net/manual/en/function.array-unique.php
You can give that a shot. You might want to make a check to ensure $postIDs will be an array, or you'll probably get a warning error.
You want all the posts to be output, but only output the title(s) once? Use SELECT DISTINCT title, url FROM posts WHERE id = $postIds; for your query
Or do you only want the first matching record output? Two choices here:
Add a LIMIT clause to the query: "SELECT * FROM posts WHERE id = $postIds LIMIT 1";
Eliminate the while() loop in the script and just call the fetchrow once.