Count likes of the latest date per user - php

I have a table "article_likes" of users and whether they like or dislike the article. With every like/dislike the datetime is saved and the id of the article. The like/dislike is saved as a bool in the "status" column.
id article_id user_id like_date status
1 8 2 2014-11-03 21:30:33 1
2 8 2 2014-11-03 21:31:00 0
3 8 3 2014-11-03 22:30:59 1
4 9 6 2014-11-03 22:36:25 1
5 9 2 2014-11-03 23:19:46 1
I like to get the amount of likes an article has. So only the status of the most recent date is valid for the count.
So the desired result would be:
article_id amount_likes
8 1
9 2
I want to get the result per article id, so not all at once.
Can anybody help me? Thanks!

This will solve your problem :)
SELECT article_id, SUM(IF(status = 1, 1, -1)) AS amount_likes FROM article_likes
GROUP BY article_id
If you store dislikes as -1 then:
SELECT article_id, SUM(status) AS amount_likes FROM article_likes
GROUP BY article_id

Try this:
SELECT `article_id`,COUNT(`user_id`) AS amount_likes FROM `links`
WHERE `status`='1' GROUP BY DATE(`like_date`), `user_id`;
Fiddle here - http://sqlfiddle.com/#!2/3b7bb6/4
Hope it helps

SELECT article_id, COUNT(IF(
SELECT CASE
WHEN status=1 THEN 'true'
ELSE 'false'
END),
'true','false'
)
)
FROM article_likes
GROUP BY article_id
ORDER BY article_id

Related

Select Distinct from new tol old in same table

I have one table named:
thread_comment
Now the table is getting filled as followed:
thread_comment_id thread_id user_id thread_comment thread_comment_time
1 2 1 This is a comment 2016-09-14 15:30:28
2 4 1 This is a comment 2016-09-14 15:32:28
3 2 1 This is a comment 2016-09-14 15:33:28
4 5 1 This is a comment 2016-09-14 15:34:28
5 7 1 This is a comment 2016-09-14 15:35:28
6 2 1 This is a comment 2016-09-14 15:37:28
7 2 1 This is a comment 2016-09-14 15:40:28
I want to show the newest threads to my page. for example:
as number one i want thread_comment_id 7
as number two i want thread_comment_id 5
I skipped 6 because i don't want any duplicates in the list.
In order to do so i did the folowing:
$sql = "SELECT DISTINCT thread_id FROM thread_comment ORDER BY thread_comment_time DESC"
This is kind of working (Not showing any duplicates). However the order does not make any sense...
For example:
It goes like 5 - 6 -4 - 7 etc...
The column used in the ORDER BY isn't specified in the DISTINCT. You need to use an aggregate function and GROUP BY to make the DISTINCT work.
SELECT DISTINCT thread_id, max(thread_comment_id) FROM thread_comment GROUP BY thread_id ORDER BY max(thread_comment_id) DESC, thread_id
EDIT: added aggregate func max()
Also thread_id is not mandatory in the ORDER BY
It I understand correctly, you want one row per thread. Here is a way to do this:
select tc.*
from thread_comment tc
where tc.thread_date = (select max(tc2.thread_date)
from thread_comment tc2
where tc2.thread_id = tc.thread_id
);

MySQL PHP Order From Another Table

I have a question.
I have 2 tables, one includes the comments and the other one includes the votes of these comments.
my comments table:
--------------------
comment_id | comment
1 abc1
2 abc2
3 abc3
4 abc4
--------------------
my voting table:
------------------
user_id comment_id | voted
1 1 1 // comment 1 has the result +1 now
2 1 1 // comment 1 has the result +2 now
3 1 2 // comment 1 has the result +1 now
4 4 1 // comment 4 has the result +1 now
5 4 2 // comment 4 has the result 0 now
------------------
Well, if a person likes a comment, it is saved as "1" to "voted". If a person dislikes a comment, it is saved as "2" to "voted".
$likes = $db->query('SELECT * FROM voting WHERE voted=1')->num_rows;
$dislikes = $db->query('SELECT * FROM voting WHERE voted=2')->num_rows;
$the_result = $likes-$dislikes;
For example, When 5 people liked a comment and 2 people disliked the same comment, the result I show is "+3".
I want to sort them using the greatest result.
Like: the first comment to show will have +4, the second one to show will have +2, the third one to show will have -2.
I want to do this in PHP. Thanks for helping.
Sorry for my bad explanation, this is my first question here. :(
I would try the following:
SELECT *,
(count(CASE WHEN vote = 1 then 1 ELSE NULL END) - (count(CASE WHEN vote = 2 then 1 ELSE NULL END))) as RESULT
FROM comments AS c
LEFT JOIN votes as v ON c.comment_id=v.comment_id
GROUP BY c.id
ORDER BY RESULT desc
Counting the votes:
Return only comment_id and the total votes:
Check the code
SELECT comment_id, SUM(
CASE voted
WHEN 1 THEN 1
ELSE -1
END) AS total
FROM voting
GROUP BY comment_id
ORDER BY total DESC;
Return with comments that has votes: Check the code
SELECT comment_id, comments, SUM(
CASE voted
WHEN 1 THEN 1
ELSE -1
END) AS total
FROM voting
INNER JOIN comments
USING(comment_id)
GROUP BY comment_id
ORDER BY total DESC;
Return all rows: Check the code
SELECT comment_id, comments, SUM(
CASE voted
WHEN 1 THEN 1
ELSE -1
END) AS total
FROM voting
RIGHT JOIN comments
USING(comment_id)
GROUP BY comment_id
ORDER BY total DESC;

" People Who Liked this Also Liked " Query in Mysql PHP

Music table
id | title
1 Rap God
2 Blank Space
3 Bad Blood
4 Speedom
5 Hit 'em up
Like table
u_id | m_id
1 1
1 2
1 4
1 5
2 3
2 4
2 5
3 1
3 5
4 1
4 2
4 5
Now if someone visits music with m_id = 1
Then the output might be like
m_id
5
2
4
To explain this a bit...
As m_id = 1 is liked by users -> {1,3,4} which in turn likes ->{2,4,5} musics. Since m_id=5 is liked by max number of users its first followed by m_id = 2 and m_id = 4.
My Try
I queried the users who liked m_id = 1
SELECT u_id FROM likes WHERE m_id =1
Then i stored in in an array and selected each of their likes and
arranged them in desc order of count.
But it is a very slow and long process is there any way i can do this ?
p.s I have heard of Association Rules and Bayesian theorem can be user to achieve this. But can anyone help me out with an example ?
You can JOIN back on the Like table and do something like this.
SELECT also_like.m_id, COUNT(also_like.m_id)
FROM [like] AS did_like
JOIN [like] AS also_like ON
also_like.u_id = did_like.u_id
AND also_like.m_id != did_like.m_id
WHERE did_like.m_id = 1
GROUP BY also_like.m_id
ORDER BY COUNT(also_like.m_id)
Essentially you are getting a list of users who liked an item then getting a complete list of those user's likes excluding the item they just liked.
You can then add a HAVING clause or LIMIT to filter things down a bit more.
using a subquery ...
SELECT m_id, count(u_id) as Rank FROM `like`
WHERE u_id in
(
SELECT u_id
FROM `like`
WHERE m_id = 1
)
AND m_id <> 1
GROUP BY m_id
ORDER BY Rank DESC
and optionally
LIMIT 0, 10
or how many "alsolikes" you want to display

Sql query to show count(*) of groups while keeping all rows of the group

I have a table similar the following
id user_id father_id
1 1 1
2 2 1
3 3 2
4 4 2
5 5 2
6 6 3
7 7 4
I search for a sql query (prefer Fluent or Eloquent for Laravel 4) to give me the following result:
id user_id father_id family_members
3 3 2 3
4 4 2 3
5 5 2 3
1 1 1 2
2 2 1 2
6 6 3 1
7 7 4 1
As it can be observed family_members is the count of users who have the same father_id
select id, user_id, father_id, count(*) as family_members from users group by father_id
The query above, just keeps the top row of each group, but I want to keep all the other records and not only the first one; then sorting them first according to the family_members and then according to father_id
How can I achieve it?
I donĀ“t know Fluent, nor Eloquent, nor Laravel 4, but the sql query would be like this.
SELECT yourTable.*, auxTable.family_members
FROM yourTable
LEFT JOIN
(
SELECT father_id, COUNT(id) as family_members
FROM yourTable
GROUP BY father_id
)auxTable ON yourTable.father_id = auxTable.father_id
ORDER BY family_members DESC, yourTable.father_id ASC
I solved the problem by the following Fluent query based on the answer from segio0983
$users = DB::table('users')
->leftjoin(DB::raw('(SELECT father_id, COUNT(id) as family_members
FROM users
GROUP BY father_id) auxTable '),function($join)
{
$join->on('users.father_id', '=', 'auxTable.father_id');
})
->orderBy('auxTable.family_members','desc')
->orderBy('users.father_id','asc')
->select('users.id','users.father_id','auxTable.family_members');

MySQL Complex query not returning right results

I have the following query:
'SELECT * FROM posts LEFT JOIN taxi ON taxi.taxiID = posts.postID
WHERE (taxi.value = 1 AND taxi.userID ='.$userID.')
AND ??????????????
ORDER BY taxi.ID DESC
LIMIT 10'
The way the site works is the user can tag posts as being "liked". When a post is liked, the taxi table is given a new row with taxiID being the same as postID, userID to store the user that liked the post, and value which is set to 1. Disliking a post sets value to 0.
I want to display all posts where value is 1 and userID is $userID - check. However, I also want the query to display all the posts where the user hasn't liked a post yet. Thing is, if the user hasn't liked a post yet, userID is NULL with a corresponding value of NULL. If I query for that, I'll be skipping those posts that other users have liked but the user hasn't.
Here's the taxi table:
ID taxiID userID value
1 1 1 1
2 1 6 1
3 1 4 0
4 2 1 0
5 2 6 1
6 2 4 0
7 3 6 1
8 3 4 0
Assuming $userID is 1, my query ought to display taxiID 1 and 3 (because user 1 liked ID 1 AND hasn't liked or disliked taxiID 3.
The code I've posted will only result in displaying taxiID 1.
The question is, what is my missing line in my query supposed to be given the above?
It seems you want to find all taxiID that the use has not disliked:
SELECT taxiID
FROM taxi
GROUP BY taxiID
HAVING taxiID NOT IN
( SELECT taxiID
FROM taxi
WHERE userID = '.$userID.'
AND value = 0
)
ORDER BY taxiID DESC
LIMIT 10
Test in SQL-Fiddle
You probably have a post table, so it would be better to use:
SELECT * --- whatever columns from `post` table
FROM post
WHERE postID NOT IN
( SELECT taxiID
FROM taxi
WHERE userID = '.$userID.'
AND value = 0
)
ORDER BY postID
LIMIT 10
If that taxi.taxiID means postID, then you should rename it to taxi.postID. It's very confusing as it is.
I had this as a comment, but I think it's my final answer:
SELECT * FROM posts
LEFT JOIN taxi ON taxi.taxiID = posts.postID
WHERE (taxi.value != 0 AND taxi.userID ='.$userID.')
OR taxi.value is null
ORDER BY taxi.ID DESC
LIMIT 10
Ok, this is what should happen with the above query:
Get all posts
Add the info from the taxi table, and associate taxi data with post data by postID
Only show if taxi.value isn't 0 (meaning it can be null or 1) AND if the userID is the same as our variable
Assuming taxi.taxiID is the same as post.ID and you're looking to select all posts not tagged by a user yet, try:
SELECT * FROM post WHERE ID NOT IN
(SELECT taxiID FROM taxi WHERE userID = 1)
this is for user with an ID=1 of course.

Categories