I have a database of Facebook Likes from several people. There are duplicate "like_id" fields across many "user_id"s. I want a query that will find the amount of "like_id"s person A has in common with person B.
This query is fantastic for comparing likes when only 2 "user_id"s are in the database, but as soon as I add a 3rd, it messes it up. Basically, I want to see who has the most "likes" in common with with person A.
SELECT *,
COUNT(*)
FROM likes
GROUP BY like_id
HAVING COUNT(*) > 1
Anyone have a query that might work?
This SQL should work. You just need to put in the User A's user_id and it should compare with all other users and show the top matching one. You can change it to show the top 5 or do whatever else you need to do.
Basically what it is doing is that it is doing a self join on the table, but making sure that when it does a join, it is a different user_id but the "like" is the same. Then it does a group by each of the other user_id's and sums the same amount of likes for that user_id.
SELECT all_other_likes.user_id, count(all_other_likes.like_id) AS num_similar_likes
FROM likes original_user_likes
JOIN likes all_other_likes
ON all_other_likes.user_id != original_user_likes.user_id
AND original_user_likes.like_id = all_other_likes.like_id
WHERE original_user_likes = USER_ID_YOU_WANT_TO_COMPARE
GROUP BY all_other_likes.user_id
ORDER BY count(all_other_likes.like_id) DESC
LIMIT 1;
Not sure what database you are using. You might need to do a SELECT TOP 1 if it is MS-SQL, but this is valid PostgreSQL and MySQL syntax.
I think this will do it:
SELECT
likes_a.user_id,
likes_b.user_id
FROM
likes as likes_a JOIN likes as likes_b
ON
likes_a.like_id = likes_b.like_id
WHERE
likes_a.user_id <> likes_b.user_id
And then post-process the results to count up who has the most in common.
Related
I am a newbie with sql queries so I have no clue how to create an accurate SQL.
I tried my best but I literally cannot find any similar example online, please help me out here.
The Data Schema as follows:
User(userID, username password, email, , userType)
Course(courseID, courseTitle)
Enroll(userID, courseID)
course rooms that users can access; note that users include all sorts of users such as teachers and administrators
Material(materialID, materialText, teacherUserID, courseID)
Question:
Find the two teachers who have access to most number of course rooms. Should there be a tie break, choose the ones with smaller user IDs. List the user ID, email, and the number of course rooms that s/he can access for the two teachers.**
The problems are:
SELECT userid, email, MIN (userid)
How can I specifically find the 2 smaller user IDs and which table should I select for finding out the course rooms? Do I have to use COUNT in this case?
FROM user JOIN enroll ON (user.usertype=enroll.userid)
As the enroll_table cannot identify whether the userID is teacher or administrator, if I use JOIN, can I find the the result that I want?
WHERE....
I don't know how to specifically find two teachers AND make sure they have tie break
Do I have to use GROUP BY and ORDER BY as well?
Just saw your attempted query. Look up how to format the code, so it stands out from the text. But you started about right. While we don't have the full info, try the following:
select user.userid,user.username, count(*) as cnt
from enroll
join user on user.userid=enroll.userid
where user.usertype="teacher"
group by user.userid
order by cnt DESC;
So Mary teaches three courses and comes out ahead. Since you want only the top two you can add the line LIMIT 2 to just get the two most prolific teachers.
The part that is hardest to understand for beginners is the group by clause, which generates aggregation, and which requires something like a count(*) clause in the first line. Read up on this separately and make yourself an even smaller example so you understand this well.
kenken068 also asked for a "tie break" using the userid so maybe the "order by" should be
order by cnt DESC, userid ASC;
Problem 1?
Limit to 2 based on the order on total. And also userid as tie braker.
Problem 2?
That info should be in User.userType
But then you need to know which userType is used for the teachers.
However, teachers have Material?
Problem 3?
See problem 1.
Problem 4?
Not always. But to calculate a total, a count is often used together with a group by.
SELECT
u.userID,
u.email,
COUNT(DISTINCT e.courseID) as TotalCourses
FROM `User` AS u
LEFT JOIN `Enroll` AS e
ON u.userID = e.userID
WHERE u.userID IN (SELECT DISTINCT teacherUserID FROM `Material`)
GROUP BY u.userID, u.email
ORDER BY TotalCourses DESC, u.userID
LIMIT 2
Select teacheruserID, count(courseID) from material
group by teacheruserID;
This will give you the count of courses the teachers have access to.
Then Simply order it in descending with the help of order by desc clause.
and the select TOP 2 with TOP Keyword
I have a table named "likes" with this structure:
id - auto generated number,
bywho - user that likes someone ,
identifier - the liked user,
tip - the category of the like
i'm trying make a list with the most liked users(identifier), my problem is:
i need to generate the ammount of likes as a computed column in the list...
here is what i tried:
SELECT u.bywho,u.identifier COUNT(DISTINCT inv_by.identifier) AS lol
FROM likes u
LEFT JOIN likes inv_by ON u.identifier = inv_by.identifier
WHERE inv_by.identifier= $this->who AND tip='profil'
GROUP BY u.identifier ORDER BY lol DESC
I expect this isn't working because of the missing comma and grouping hasn't occured by u.bywho. The problem with doing that is it will give you a breakdown of the count by the person being liked and who liked them. Assuming a person can never be liked more than once, the count would always be one.
Try adding the comma after u.identiier in the select clause as mentioned by another reply.
If that doesn't work try grouping by u.who as well.
If that doesn't work as expected please explain what you expect a liitle more.
I'm guessing you may want to remove something from the select clause. Whatever non-aggregate is left in the select clause needs to be grouped upon.
I need to create a mysql query for my project that's a bit too complicated for my scope...
So, I a table of images with id and timestamp columns, along with metadata columns
I also have a table of "loves", which has columns for id, imageid, userid, and timestamp
(userid not really important here)
Currently, I am using a LEFT JOIN to sort the images by their total number of likes
What I would like to do now is, instead, sort the images by their daily average of likes.
So, an image created today that has 5 likes associated with it should come before an image created 5 days ago with 20 likes associated.
Not even sure how to begin to approach this, any of you SQL gurus have any ideas? Cheers.
EDIT:
Using this query
SELECT images.*,
COUNT(loves.id) AS num_loves
FROM images
JOIN loves ON (images.id = loves.imageid)
GROUP BY images.id
ORDER BY num_loves/DATEDIFF(images.timestamp,CURDATE())
DESC LIMIT 0 , 24
getting this error
Reference 'num_loves' not supported (reference to group function)
Still getting a handle on MySQL syntax...
You can use any valid expression as your ORDER BY clause. This means we just need to recall a hint of algebra:
SELECT
images.url,
images.date_added
FROM IMAGES
JOIN image_likes ON image_likes.image_id = images.id
GROUP BY images.id
ORDER BY count(image_likes.id)/DATEDIFF(CURDATE(), images.date_added)
I have a (what I am hoping to be easy) problem with a MySQL query.
I have 2 tables: articles, comments
An article can have many comments so there is a foreign of article_id in the comments table.
I want to get all the articles and while loop them to show on the page and then get all the comments count for each article. Easy, this is done. Now the problem is I want to sort the results based on number of comments but still show the results in the same way.
So basically I want to:
SELECT *
FROM tbl_articles
JOIN tbl_comments
ORDER BY (the most comments);
I am hoping this can all be done in a single query as the entire query is build dynamically from multiple sets of checkboxes where a single query could look like:
SELECT *
FROM tbl_articles
WHERE subject IN (1,2,5)
AND medium IN (1,3)
AND date_active > NOW()
AND...
Any further information I am happy to provide.
Something like...
SELECT *, COUNT(tbl_comments.id) as comments_count
FROM tbl_articles JOIN tbl_comments ON (tbl_comments.article_id = tbl_articles.id)
GROUP BY tbl_comments.article_id
ORDER BY comments_count;
In my web application, I would like to show a list of my users. Users can have different statuses (FB-like). I want to display the last 3 statuses below each user's name.
Dinosaur
I'm a dino!
I eat meat!
I like cows!
Fish
Blub!
I don't like dinosaurs!
Going for a swim!
I have the following SQL query:
SELECT s.status, u.voornaam, u.achternaam FROM status AS s INNER JOIN sportjefit_user AS u ON s.user = u.id where u.begeleider='53' group by id desc limit 3
However, this returns only the top 3 of the results, in this case it would only show the Dinosaur's statuses. I want to show the top 3 statuses for every users though. Can I do this with a group by and put a limit on this or do I need multiple queries here? And, if I do need multiple queries, how would I go about implementing this? The number of users will keep increasing as my application grows.
Can someone help me out?
Thanks.
I'd use multiple queries like this:
select all users
for each user
select last 3 statuses
using
SELECT * FROM sportjefit_user
and
SELECT status FROM status WHERE userid = ? ORDER BY id DESC LIMIT 3
How many users do you anticipate? If you're trying to show all users on a page, I'd paginate them. Hope this helps.