PHP & MySQL pagination display problem - php

When I set my pagination to display 10 comments at a time my comments query wont count the comments replies as part of the display count how can I fix this so that my comments replies are counted? My comments replies queries are nested in my main query to display comments.
Query for pagination
SELECT COUNT(comment_id) FROM comments WHERE id = $id
The main query to display comments.
$dbc = mysqli_query($mysqli,"SELECT comments.*, users.*
FROM comments
LEFT JOIN users
ON comments.user_id = users.user_id
WHERE id = '" . $id . "'
AND parent_comment_id = 0
LIMIT $start, $display");
The main querys reply comments.
//display comments replies
$dbc2 = mysqli_query($mysqli, "SELECT comments.*, users.*
FROM comments
LEFT JOIN users
ON comments.user_id = users.user_id
WHERE id = '" . $id . "'
AND parent_comment_id >= 1");
//display comments replies
$dbc3 = mysqli_query($mysqli, "SELECT comments.*, users.*
FROM comments
LEFT JOIN users
ON comments.user_id = users.user_id
WHERE id = '" . $id . "'
AND parent_comment_id >= 1");

Maybe this query, could you give the precise DB structure to work with.
SELECT
com1.*,
users.*,
(
SELECT COUNT(*)
FROM comments AS com2
WHERE com2.parent_comment_id = com1.id
) AS num_replies
FROM comments AS com1
LEFT JOIN users ON com1.user_id = users.user_id
WHERE
com1.id = '" . $id . "'
AND com1.parent_comment_id = 0
LIMIT $start, $display

Related

How to display posts from followers and logged-in user in news feed?

I want to display posts from the users being followed and the logged in user using a single PHP MySql query.
I have three tables:
users (user_id, username, ..)
posts (post_id, content, added_by, ..)
Followers (f_id, followed, followed_by)
I have variable
$id = $_SESSION['user_id']
$que = $db->prepare("SELECT posts.*, users.*, followers.follow, followers.followed_by FROM posts
INNER JOIN users ON users.user_id = posts.added_by_user_id
LEFT JOIN followers ON followers.follow = posts.added_by_user_id
WHERE (posts.added_by_user_id = $id OR followers.followed_by = $id) ORDER BY post_id DESC");
$que->execute();
$posts = $que->fetchAll();
But the query shows each post created by logged-in user twice.
You can use any of the following:
Add additional clause to you LEFT JOIN followers and it will do the trick i.e LEFT JOIN followers ON ( followers.follow = posts.added_by_user_id AND followers.followed_by = $id ) . Note the AND
$que = $db->prepare("SELECT posts.*, users.*, followers.follow, followers.followed_by FROM posts
INNER JOIN users ON users.user_id = posts.added_by_user_id
LEFT JOIN followers ON ( followers.follow = posts.added_by_user_id
AND followers.followed_by = $id )
WHERE (posts.added_by_user_id = $id OR followers.followed_by = $id)
GROUP BY( posts.post_id )
ORDER BY post_id DESC");
$que->execute();
$posts = $que->fetchAll();
Anotber way using your code, just add DISTINCT after SELECT. I.e SELECT DISTINCT posts.* .....
Another way is using sub query
$que = $db->prepare("SELECT posts.*, users.* FROM posts
INNER JOIN users ON users.user_id = posts.added_by_user_id
WHERE posts.added_by_user_id= $id OR posts.added_by_user_id IN (SELECT follow FROM followers WHERE followed_by= $id)
ORDER BY post_id DESC");
$que->execute();
$posts = $que->fetchAll();
You can also use the below. The key function is GROUP BY
$que = $db->prepare("SELECT posts.*, users.*, followers.follow, followers.followed_by FROM posts
INNER JOIN users ON users.user_id = posts.added_by_user_id
LEFT JOIN followers ON followers.follow = posts.added_by_user_id
WHERE (posts.added_by_user_id = $id OR followers.followed_by = $id)
GROUP BY( posts.post_id )
ORDER BY post_id DESC");
$que->execute();
$posts = $que->fetchAll();
(I'm not too sure how efficient this is)

count all posts in table "posts" regarding users from table "users"

two tables - posts and users
column posts.user is matching with users.id.
I want to count all posts from all users, this way:
user1 5
user2 3
user3 9
... and so on meaning that user1 from users has 5 instances from posts... etc.
$items = '';
$sql = "select users.name, posts.user from users inner join posts on users.id = posts.user";
$stmt = $db->query($sql);
while($row = $stmt->fetch()){
$count = $stmt->rowCount();
$items .= "<div><span class='spanuser'>" . $row['name'] . "</span> <span class='spancount'>" . $count . "</span></div>";
}
echo $items;
result
user1 74 // 74 is total number of `posts` rows
user2 74
user3 74
... all users - 74
Any help?
You need to use GROUP BY with LEFT JOIN, e.g.:
SELECT u.name, COUNT(p.id) AS `count`
FROM users u LEFT JOIN posts p ON u.id = p.user
GROUP BY u.name;
This will give you the desired output.
Update
As per our discussion, to get the count for today, you can use the following query:
SELECT u.name, COUNT(p.id) AS `count`
FROM users u LEFT JOIN posts p ON u.id = p.user
WHERE DATE(datetime) = DATE(NOW())
GROUP BY u.name;
Similarly, you can use BETWEEN operator to get the same count for a date range, e.g., for last 7 days, you can use this:
SELECT u.name, COUNT(p.id) AS `count`
FROM users u LEFT JOIN posts p ON u.id = p.user
WHERE DATE(datetime) BETWEEN DATE_ADD(NOW(), INTERVAL -7 DAY) AND DATE(NOW())
GROUP BY u.name;
Also, you need to update the php to use the count returned by the query and not rowCount, e.g.:
$items .= "<div><span class='spanuser'>" . $row['name'] . "</span> <span class='spancount'>" . $row['count'] . "</span></div>";
Try doing it this way using Count()
$items = '';
$sql = "SELECT u.name,COUNT(p.user) as pCount FROM users u INNER JOIN posts p on u.id = p.user GROUP BY u.name";
$stmt = $db->query($sql);
while($row = $stmt->fetch()){
$items .= "<div><span class='spanuser'>" . $row['name'] . "</span> <span class='spancount'>" . $row['pCount'] . "</span></div>";
}
echo $items;
Try use COUNT(). To count the posts.user
https://www.w3schools.com/sql/sql_count_avg_sum.asp
You want to group by the user and count the number of posts, to get the final total row you want a WITH ROLLUP e.g.
SELECT COALESCE(User,'TOTAL') AS Name,
Count(Post.ID) AS CountOfPosts
FROM Users
LEFT JOIN Posts ON Posts.USer= Users.id
GROUP BY Users.id WITH ROLLUP
The "total" row will actually have a value of null so we use the COALESCE to change null into TOTAL

MySQL Sum with Join

I have been trying to do a sum with a join with no luck. What I need is to get a total from product_price (located in tbl_products) based on a product_id which is located in both tbl_basket and tbl_products.
So far I have:
$result = mysql_query("SELECT * FROM tbl_basket a INNER JOIN tbl_products b ON a.product_id = b.product_id WHERE a.customer_id = '" . $_SESSION['user'] . "'");
This works to get the product_name from tbl_products based on the product_id stored in tbl_basket. I know I need a COUNT which I have tried numerous ways but with no luck. I have chosen to show a query I know works for something as my syntax for the COUNT I tried was way off. Thank you.
Does this not work?
$result = mysql_query("SELECT sum(b.product_price) as total_price FROM tbl_basket a INNER JOIN tbl_products b ON a.product_id = b.product_id WHERE a.customer_id = '" . $_SESSION['user'] . "'")

Optimizing Small MySQL Join Query

I have a list of venues in the Venues table, and a list of a cities/states in the Locations table. The venue is associated with an area code unique to my organization, referred to as a SOYID. The SOYID is made up of a geographical area - each row in the Locations table has a City, State, and the corresponding SOYID. Some Venues rows have a SOYID, others do not; for those that do not, I need to find the SOYID for the city and state listed. I only want to select those Venues in a specific SOYID.
This query works, however, it takes a few seconds to load; I don't think I am writing the query correctly. Currently Venues has approx 140 rows, Locations has 40,000.
$sql = "SELECT DISTINCT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr
FROM Venues AS a LEFT JOIN Locations AS c ON a.City = c.city
WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "'
OR ((c.city = a.City) AND (c.state = a.StateAbbr) AND (c.SOYID = '" . mysql_real_escape_string($SOYID) . "'))
ORDER BY a.Name ASC";
Any time you reference a column from a LEFT JOINed table (c.state and c.SOYID in your specific case) in the WHERE clause, you force that join to behave like an INNER JOIN. Instead, make those tests part of the join condition:
"SELECT DISTINCT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr
FROM Venues AS a
LEFT JOIN Locations AS c
ON a.City = c.city
AND a.StateAbbr = c.state
AND c.SOYID = '" . mysql_real_escape_string($SOYID) . "'
WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "'
OR c.SOYID IS NOT NULL /* LEFT JOIN found a matching row */
ORDER BY a.Name ASC"
EDIT: Based on comments, this version should allow you do remove the DISTINCT requirement:
"SELECT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr
FROM Venues AS a
WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "'
OR EXISTS(SELECT NULL
FROM Locations AS c
WHERE a.City = c.city
AND a.StateAbbr = c.state
AND c.SOYID = '" . mysql_real_escape_string($SOYID) . "')
ORDER BY a.Name ASC"

PHP & MySQL Error - Duplicate column name 'user_id'

I get the following Error below from my query, and was wondering how can I fix this problem?
Duplicate column name 'user_id'
Here is My MySQL query.
"SELECT COUNT(users_friends.user_id) FROM ((SELECT *
FROM users_friends
INNER JOIN users ON users_friends.user_id = users.user_id
WHERE users_friends.user_id = '" . $user_id . "'
AND users_friends.friendship_status = '1')
UNION
(SELECT *
FROM users_friends
INNER JOIN users ON users_friends.friend_id = users.user_id
WHERE users_friends.friend_id = '" . $user_id . "'
AND users_friends.friendship_status = '1')) as friends"
Here is my new query.
SELECT COUNT(user_id) FROM ((SELECT users_friends.user_id
FROM users_friends
INNER JOIN users ON users_friends.user_id = users.user_id
WHERE users_friends.user_id = '" . $user_id . "'
AND users_friends.friendship_status = '1')
UNION
(SELECT users_friends.user_id
FROM users_friends
INNER JOIN users ON users_friends.friend_id = users.user_id
WHERE users_friends.friend_id = '" . $user_id . "'
AND users_friends.friendship_status = '1')) as friends
There's a couple of problems here. You obviously (read humor) only want a row count, so no need to SELECT *, true? I'm assuming you want to use a UNION to add rows together... Thus:
SELECT COUNT(*) AS the_count
FROM
(SELECT user_id AS ID
FROM users_friends
INNER JOIN users ON users_friends.user_id = users.user_id
WHERE users_friends.user_id = '" . $user_id . "'
AND users_friends.friendship_status = '1'
UNION
SELECT friend_id AS ID
FROM users_friends
INNER JOIN users ON users_friends.friend_id = users.user_id
WHERE users_friends.friend_id = '" . $user_id . "'
AND users_friends.friendship_status = '1'
) AS uf1;
Note: I'm assuming that the rest of the query (inner join, where, etc) works.
Edited, fixing the syntax problem with the ambiguous field names for ya.
SELECT COUNT(*) AS the_count
FROM
(SELECT uf.user_id AS ID
FROM users_friends uf
INNER JOIN users u ON uf.user_id = u.user_id
WHERE uf.user_id = '" . $user_id . "'
AND uf.friendship_status = '1'
UNION
SELECT uf.friend_id AS ID
FROM users_friends uf
INNER JOIN users u ON uf.friend_id = u.user_id
WHERE uf.friend_id = '" . $user_id . "'
AND uf.friendship_status = '1'
) AS uf1;
You are using SELECT * from , bringing all columns from 2 tables user_friends and users, both of them have a column called user_id. When you use a UNION it is my understanding that a temporary table is created, so MySQL is complaining that you have 2 columns with the same name. Try to explictly define the user_id you want to use for instance SELECT users.user_id, user_friends.abc etc
Edit:
If i understand this correctly, you are trying to get user ids of the friends.To me it seems like your previous query would return the $user_id in all records.
Try this:
SELECT COUNT(*) as CNT FROM
(
(SELECT users.user_id as uid
FROM users_friends
JOIN users ON users_friends.user_id = users.user_id
WHERE users_friends.friend_id = '" . $user_id . "'
AND users_friends.friendship_status = '1')
UNION
(SELECT users.user_id as uid
FROM users_friends
JOIN users ON users_friends.friend_id = users.user_id
WHERE users_friends.user_id = '" . $user_id . "'
AND users_friends.friendship_status = '1')
) as myfriends

Categories