display count = 0 for id not exists in foreign table - mysql

I have these tables
articles_type
id type
1 article
2 free
3 review
user_fav
uid article_type_id
1 1
1 2
2 1
3 2
3 3
4 1
4 2
4 3
I need to back user with article type if user do not added type then display 0
the expected result
for uid = 1
article_type_id count
1 1
2 1
3 0
------------------------------
for uid = 2
article_type_id count
1 1
2 0
3 0
------------------------------
for uid = 3
article_type_id count
1 0
2 1
3 1
------------------------------
for uid = 4
article_type_id count
1 1
2 1
3 1
I have tried the following query to get the expected result.
QUERY:
select article_type_id, count (article_type_id)
from article_types
left join user_fav on user_fav.article_type_id = article_type.id
where uid = 1

When the condition is in the second table of a left join, then you need to include it the on clause. Also, your query needs a group by:
The query you want is:
select a.article_type_id, count(*)
from article_types a left join
user_fav u
on u.article_type_id = a.id and u.uid = 1
group by a.article_type_id;

select article_type_id, coalesce(count(article_type_id),0)
from article_types
left join user_fav on user_fav.article_type_id = article_type.id
where uid = 1

Related

How to get all value after where contain in sql

I get stuck in query of sql for this task
If i get all field after contain value 2 and ignore before value 2
For example like this
id profile_id status
1 1 3
2 1 3
3 1 2
4 1 1
5 1 1
and the result when i try like this, show all values where not contain 2
SELECT * FROM `users` WHERE `status` <> 2
id profile_id status
1 1 3
2 1 3
4 1 1
5 1 1
i try code subquery like this
SELECT *
FROM `users`
WHERE `users`.status != (
SELECT us.status
FROM `users` us
WHERE us.status = 2 LIMIT 1)
and the result show like this
id profile_id status
1 1 3
2 1 3
4 1 1
5 1 1
The result should i expected be like this, just show all field after the status = 2
id profile_id status
4 1 1
5 1 1
Thanks for your help
Try below query:
SELECT *
FROM `users`
WHERE id > (
SELECT id
FROM `users`
WHERE status = 2
)

How to sum counted rows if same source id

Good Day,
I was creating a function where a user can share a post and other users may "LIKE or Comment" on it..
now on my POST table I have "id" and "source_id" + other details, to track people who like a post I created a table dedicated for like details. with columns: ID, USER_ID ( id of use who liked the post ), post_id
posts table:
id | source_id | caption
1 1 original post
2 1 share from id: 1 posts
3 3 new posts
4 4 new posts
likes table:
id | post_id | user_id
1 1 2
2 1 10
3 2 11
4 2 4
5 2 20
6 3 11
7 4 19
8 4 10
in order to count the number of like for a post, I do
SELECT a.id, a.source_id,b.num_likes
FROM posts AS a
LEFT JOIN (SELECT COUNT(user_id) AS
num_likes,post_id
FROM post_likes GROUP BY post_id ) AS b
ON b.post_id= a.id
WHERE b.num_likes != 0
result:
id | source_id | num_likes
1 1 2 <--- original post
2 1 3 <--- shared post who also got likes
3 3 1
4 4 2
what I would like to achieve is like these
id | source_id | num_likes
1 1 5
3 3 1
4 4 2
is this possible to achieve by just a query ? if so, could you please help me achieve this..
Thank you very much!
You can join the tables directly.
SELECT MIN(a.id), a.source_id, COUNT(b.num_likes) FROM posts AS a
LEFT JOIN post_likes AS b ON b.post_id= a.id
GROUP BY a.source_id
HAVING b.num_likes > 0
Might need to use a MIN for a.id since it is not aggregated. It would depend on your data and use case.
Use SUM function to get the total likes.
SELECT min(a.id) as id, a.source_id,sum(b.num_likes) as num_likes
FROM posts AS a
LEFT JOIN (SELECT count(1) AS
num_likes,post_id
FROM post_likes GROUP BY post_id ) AS b
ON b.post_id= a.id
WHERE b.num_likes != 0
GROUP BY a.source_id

Select WHERE IN and LIMIT by number of rows

I have a table which looks like this
userid | value | time
1 0 1
1 1 2
1 2 3
3 5 4
4 6 5
1 9 6
3 10 7
Using a select where in query I would want to select userd, value, and time but limit the total number of rows pulled for each userid
My SELECT query,
select userid, value, time from table where userid in (1,3) order by time desc;
This query outputs all the values like so
userid | value | time
1 0 1
1 1 2
1 2 3
3 5 4
3 10 7
I would hover want to limit the number of rows for each userid to two to get an output like so
userid | value | time
1 0 1
1 1 2
3 5 4
3 10 7
I tried using limit but that limits the number of rows for the entire output.
You can use a rank query to limit rows per user
select userid,
value,
`time`
from (
select *,
#r:= case when #g = userid then #r + 1 else 1 end row_num,
#g:=userid
from test t
cross join (select #g:= null,#r:=0) t1
where userid in (1,3)
order by userid,value,`time` desc
) t2
where row_num <= 2
Above query will give rank to each record for same user like user 1 has 3 records the they will assigned rank as 1,2,3 and if user 2 has 2 records then rank will be 1,2 for user 2 and in parent query i am just filtering the records according to the rank that return only result where rank is less than equal to 2 for for each user only 2 rows with rank 1 and 2 will be returned
Demo

Attempting to join and group data

I have two tables. The first is property and the second is category
The structure of the property table is:
id propertyname
1 a
2 b
3 c
4 d
and the structure of category is:
id propid catid
1 1 2
2 1 3
3 2 1
4 3 1
5 3 2
6 4 3
I'm trying to create a result like this:
id propertyname propid catid
1 a 1 2,3
2 b 2 1
3 c 3 1,2
4 d 4 3
How can I get this result? I used a group by clause and group_concate() function but it doesn't seem to work.
Here is what I've tried:
SELECT prop.*,category.property_id cat_prop,category.type_id type
FROM tbl_property prop,
tbl_category_type category
WHERE prop.id=category.property_id
Try this:
SELECT t0.id, t0.propertyname, group_concat(t1.catid)
FROM t0
INNER JOIN t1 ON t0.id = T1.propid
GROUP BY id
That should give you your result

Mysql SUM based another calculated filed condition

There are three tables Users, Lists, Details. Here it is my table structure and data sample
userid username | list_id list_val user_id | detail_id list_id multipler
1 user1 | 1 500 1 | 1 1 3
2 user2 | 2 300 1 | 2 1 2
3 user3 | 3 600 1 | 3 2 1
4 100 2 4 2 1
5 3 4
SELECT
users.username,
SUM(lists.lists_var),
FROM
users
INNER JOIN lists ON users.userid = lists.user_id
GROUP BY
users.username
HAVING
(SELECT (exp(sum(log(COALESCE(details.multipler, 1))))) FROM details WHERE
details.list_id = lists.list_id) > 3
This query gives me result
user1 - 1400
But I want something IF multipler_total > 3 THEN SUM(list_val) so result must be:
user1 - 1100
try this:
SELECT
users.username,
SUM(lists.lists_var),
FROM
users
INNER JOIN lists ON users.userid = lists.user_id
INNER JOIN (SELECT list_id, SUM(multiplier) mult_total FROM details GROUP BY list_id) d
ON d.list_id = lists.list_id and d.mult_total > 3
GROUP BY
users.username