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
Related
May I know how to join two columns table into as 1 column?
For example:
Edited
first_table
id | folder | category id | status
1 Peter 5 0
2 John 6 1
3 Shawn 7 0
second_table
id | filename| category id
1 123.sql 9
2 you.png 12
3 it.pdf 11
I want expected result like below, column folder and filename become store in 1 column and
column name as folder_filename :
First table join Second table
id | folder_filename| category id | status
1 Peter 5 0
2 John 6 1
3 Shawn 7 0
4 123.sql 9
5 you.png 12
6 it.pdf 11
I tried below this sql, but not sure how to modify make it work.
SELECT * FROM first_table INNER JOIN second_table
Hope someone can guide me how to solve it. Thanks.
You seem to want union all:
select f.id, f.folder, f.category_id
from first_table f
union all
select s.id, s.folder, s.category_id
from second_table s;
EDIT:
If you actually want to change the ids, then:
select row_number() over (order by which, id) as id, folder, category_id
from ((select f.id, f.folder, f.category_id, 1 as which
from first_table f
) union all
(select s.id, s.folder, s.category_id, 2
from second_table s
)
) fs
) fs
I have 3 tables:
Question (id, questionText)
QuestionCategory (id, categoryName)
Question_QuestionCategory (questionId, categoryId)
Sample Data:
Table Question:
id | questionText
1 | 2 + 2 = ?
2 | 10 x 5 / 3 + 5 = ?
3 | USA is located in which continent?
Table QuestionCategory:
id | categoryName
1 | Easy
2 | Hard
3 | Math
4 | Geography
Table Question_QuestionCategory:
questionId | categoryId
1 | 1
1 | 3
2 | 2
2 | 3
3 | 1
3 | 4
The Question_QuestionCategory table is a relation table that stores the foreign keys from the question and questionCategory tables.
My problem is: I need a select that returns to me a question that has the Hard and Math categories at the same time (the question with id 2 in this case). How can I do that?
You can do that by using aggregation an checking if the distinct count of categories is equal to the number of categories you asked for. To only get one row as a result you can use LIMIT.
SELECT q.id,
q.text
FROM question q
INNER JOIN question_questioncategory qc
ON qc.question = q.id
INNER JOIN questioncategory c
ON c.id = qc.categoryid
WHERE c.categoryname IN ('Hard',
'Math')
GROUP BY q.id,
q.text
HAVING count(DISTINCT c.categoryname) = 2
LIMIT 1;
I have the following query which populates a join table with all 'theme' options for a given user.
INSERT INTO join_themes_users (join_theme_id, join_user_id);
SELECT theme_id, 1
FROM themes
What I now need to do is edit this query to populate the join table with all theme options for all users
Can this be done in a single query or will I need to create a for loop in PHP?
The above query produces results looking something like...
join_id | user_id | theme_id
----------------------------------------------------
1 1 1
2 1 2
3 1 3
...
What I need is something like this...
join_id | user_id | theme_id
----------------------------------------------------
1 1 1
2 1 2
3 1 3
...
14 2 1
15 2 2
16 2 3
...
27 3 1
28 3 2
29 3 3
...
To get all combinations you cross join the tables:
INSERT INTO join_themes_users (join_theme_id, join_user_id)
SELECT themes.theme_id, users.user_id
FROM themes
CROSS JOIN users
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
Please allow me to as a stupid question again.
It is really hard for me to call query mysql from both tables.
post_table
PostID | UID_frm
10 | 1
10 | 2
10 | 3
10 | 4
10 | 5
user_table
Name | FID
tom | 2
tom | 3
henry | 4
I want to have this below as result.
UID_frm
2
3
1
4
5
It is the result from column UID_frm but priority order by user_table.FID.
Please advise I want to call like this:(but doesn't work)
select UID_frm
from post_table
where PostID='10'
order by (select FID
from user_table
where Name='tom')
I think this is what you are looking for:
SELECT UID_frm
FROM post_table a
LEFT JOIN user_table b
ON a.UID_frm = b.FID
WHERE PostID = '10'
ORDER BY (IF(b.Name = 'tom', b.FID, NULL)) ASC, a.UID_frm ASC
Try this
select PT.UID_frm
from post_table as PT,user_table as UT
where UT.FID=PT.UID_frm and PT.PostID='10'
order by UT.name ASC/DESC