SQL get all users activity summed in a query - php

I want get all users from users table and have a column summed up on all articles length written by all users from article table
Basically
Here is a code if I choose to run an SQL query for each loop (not good)
SELECT * FROM users
--loop
SELECT SUM(wordcount) AS totalwordcount FROM articles WHERE writer_id = user_id
I have used LEFT JOIN but I can only get a list of users with their user_id present on article table
SELECT users.name, SUM(article.wordcount) AS xox FROM users LEFT JOIN article ON users.id_usera = article.writer_id WHERE article.editor_status = 'finished' ORDER BY users.id_usera
With this query, I only get users with their user_id present in the article table but I want all users listed and NULL/empty returned if the user has no article with his/her id present

You need GROUP BY:
SELECT u.name, SUM(a.wordcount) AS xox
FROM users u LEFT JOIN
article a
ON u.id_usera = a.writer_id AND
a.editor_status = 'finished'
GROUP BY u.name;

SELECT users.name, SUM(article.wordcount) AS TotalWordCount
FROM users
LEFT JOIN article ON users.id_usera = article.writer_id
WHERE article.editor_status = 'finished'
GROUP BY article.writer_id
ORDER BY users.id_usera

Related

What Sql Join can I use to combine my three tables

I made a query that user can see all the post of active users but not of those inactive, but also they should not see the post of users they blocked or blocked them how can I do that?, the block_users table has block_by_userid and blocked_userid column.
I tried INNER JOIN the post table with members table which every inactive users post cannot be seen anymore., How will I combine the block_users table?
$GetPost = "SELECT Post.* FROM Post
INNER JOIN Members ON Post.Poster_user_id = Members.User_id
WHERE Status='active'";
you might try FULL OUTER JOIN
the idea it to get all items in both tables member and block_users and then filter the data using where clause, i am sorry if i miss using the fields name , so please check the tables names, i assume block_users.block_by_userid contained the blocked user id if not use the correct field
$GetPost = "SELECT Post.* FROM Post
INNER JOIN Members ON Post.Poster_user_id = Members.User_id
FULL OUTER JOIN block_users ON Members.User_id = block_users.user_id
WHERE Status='active'
AND
WHERE block_users.block_by_userid != Members.User_id";
Suppose I am doing this for a user xyz whose user_id is 123 then below is a query which will return expected output for user 123.
Query:
SELECT Post.* FROM Post
INNER JOIN Members ON Post.Poster_user_id = Members.User_id
WHERE Status='active' and post.poster_user_id NOT IN(select block_by_userid from block_users where blocked_user_id = 123 UNION select blocked_user_id from block_users where block_by_userid = 123)

joining 2 tables in msqli

table posts
table users
how would i count posts for specific user logged in. for example when user with id 3 is logged in it should show me 4 posts
I already did it for total posts count:
<?php
$post_query1 = "SELECT count(*) AS total FROM posts ";
$post_result1 = mysqli_query($db, $post_query1);
$post1 = mysqli_fetch_array($post_result1);
?>
Try below example :
select count(*) as total from user as u inner join post as p on p.id_user = u.id_user AND u.id_user = 3
If you want to get only the posts count for the particular user, say user with id = 3, your query should be this:
$query = "SELECT count(*) AS total FROM posts WHERE id_users = 3";
But if you want to get both the posts count as well as the user information and other post information, you will have to run a join query on both the users and posts table. Your query would now become:
$query = "SELECT u.*, p.*, count(p.id_posts) FROM users AS u JOIN posts AS p ON u.id_users = p.id_users WHERE p.id_users = 3";
Some Useful Notes
p.* - * is a wildcard character that means get all the columns in the posts table
u.* - * is a wildcard that means get all the columns in the users table
posts as p - AS is for aliasing. So, we are giving posts table a temporary name.
Here are the different types of the JOINs in SQL:
(INNER) JOIN: Returns records that have matching values in both tables
LEFT (OUTER) JOIN: Return all records from the left table, and the matched records from the right table
RIGHT (OUTER) JOIN: Return all records from the right table, and the matched records from the left table
FULL (OUTER) JOIN: Return all records when there is a match in either left or right table
Note: It is necessary that you have to join two/more tables only with the help of foreign key. Without the foreign key is is meaningless to join two or more tables
Reference 1: https://www.w3schools.com/sql/sql_join.asp
Reference 2: https://www.tutorialspoint.com/mysql/mysql-using-joins.htm
As per the Question what you have asked to join the tables
Query:
SELECT * FROM TABLE 1 JOIN TABLE 2 ON TABLE1.id = TABLE2.id WHERE TABLE2.ID=3
Kindly replace TABLE1 & TABLE2 with the Tables that are to be joined and the id with the foreign key what you have specified in the Table.
Hope so this might be helpful for you to write your own code in future. Happy Coding :)
You have only to use a simple join.
SELECT count(*)
FROM USER u,
post p
WHERE p.id_user = u.id_user
AND u.id_user = 3

SQL to Get Data Other User Data from Same Group

I'm having a hard time wrapping my head around the SQL I need to pull data about other users that belong to the same group as the logged in user in my PHP application.
The data structure looks like this:
User Table
user_id
name
status
bio
Group Table
group_name
user_id
What I'm trying to do is create a page that shows the bios for all of the other members of the same group or groups that a user belongs to.
I've tried this SQL:
SELECT list.listname, list.user_id, list.groupname
FROM list
LEFT JOIN user_group ON list.user_id = user_group.user_id
WHERE user_group.user_id = 'test#testuser.com'
ORDER BY list.groupname
But I just get back the bio for test#testuser.com, and no other bios. If I remove the WHERE portion of the statement, I get all bios for all users, and not just the bios of users that are in the same group as my test#testuser.com. The logged in user may belong to more than one group.
Any ideas about how to grab this data?
This returns the groups for a given user:
SELECT l.groupname
FROM list l
WHERE l.user_id = 'test#testuser.com'
ORDER BY l.groupname;
If you want all users in the groups
SELECT l.listname, l.user_id, l.groupname
FROM list l LEFT JOIN
user_group ug
ON l.user_id = ug.user_id
WHERE l.groupname IN (SELECT l2.groupname
FROM list l2
WHERE l2.user_id = 'test#testuser.com'
)
ORDER BY l.groupname;
You can do it by self-joining the list table:
SELECT l.listname, l.user_id, l.groupname
FROM list l
LEFT JOIN user_group ug ON l.user_id = ug.user_id
INNER JOIN list l2 ON l2.groupname = l.groupname
AND l2.user_id = 'test#testuser.com'
ORDER BY l.groupname;

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.

joining two tables based on cookie data

I am making a cookie based favorite system and need to join data from two tables based on the unique user id stored in the cookie so I can tell what items that use has marked as favorites.
I know I need to do a JOIN but have not used them much and dont really have my head around them yet.
Existing query that selects the items from the db:
$query = mysql_query("SELECT *, UNIX_TIMESTAMP(`date`) AS `date` FROM songs WHERE date >= DATE_SUB( NOW( ) , INTERVAL 2 WEEK ) ORDER BY date DESC");
My favorites table is setup as: ID FAVORITE USERID where ID is the primary key, FAVORITE is the song ID from table songs and USERID is a hash stored in a cookie.
I need to join in all the rows from the favorites table where the USERID field matches the cookie hash variable.
I also need to gather the total number of rows in favorites that match the song id so I can display a count of the number of people who set the item as favorite so I can display how many people like it. But maybe need to do that as a separate query?
This should do it, I would imagine:
$user_id = intval($_COOKIE['user_id']);
$query = mysql_query(sprintf("
SELECT *
FROM songs s
INNER JOIN favorites f
ON f.favorite = s.id
WHERE f.userid = %s
", $user_id));
You should probably read up on the different types of joins.
And then to get the total amount of rows returned, you can just call mysql_num_rows on the result:
$favorite_song_count = mysql_num_rows($query);
EDIT: To select all songs but note which are favorited, you would do this:
$query = mysql_query(sprintf("
SELECT s.*, f.id as favorite_id
FROM songs s
LEFT JOIN favorites f
ON f.favorite = s.id AND f.userid = %s
", $user_id));
By switching it from an INNER JOIN to a LEFT JOIN we are selecting all songs even if they don't have a corresponding record in the favorites table. Any songs that are favorites of the user_id provided will have a non-NULL value for favorite_id.
You can have logical (and, or, ...) operators in join conditions:
select t1.*
from t1
join t2 on t1.id = t2.fid and t2.foo = 'blah'
If you are also querying the total number of times each song has been "favorited" then you need a group by construct also, like this way:
select *, count(f.id)
from songs as s
left join favorites as f on s.id = f.favorite and f.userid = <hash>
group by s.id

Categories