Randomize a winner pair from the subscriptions - mysql

I have a project, where customer needs a winnner pair for events. The users of this site can "like" other user's (just like on FB), they subscribe to a particular post, and the script will generate a winner pair from the subscribers.
So I need a SQL query to randomize a winner pair from the list of pairs, where the users liked each other, and subscribed to a particular post.
How do i do that ?
I cant write a query that, because i got unexpected results.
I have 3 tables : events, likes, subs (and users ofc)
events table : event_id, event_name
subs table: sub_id, event_id, uid
likes table: liker, liked (the two uid from the users table)
Now I can make pairs from the likes table (i self-joined the table where liker = liked AND liked = liker) and randomized, but how can I join the subs and the events tables to the likes table to achieve that a randomized pair will be a subscribed users for a particular event too ?
My current query looks like this :
SELECT L.liked AS T1, L.liker AS T2
FROM likes AS L, likes AS K
WHERE L.liked = K.liker
AND L.liker = K.liked
ORDER BY rand( )
LIMIT 0 , 1
I googled everything about joins for one week, but i cant achieve that.

Related

Saving user interactions and presenting them

I have a site where users vote on polls. They can also like these polls. When they scroll through their feed, the questions they've liked will be represented by a like icon being filled (kind of like Facebook or Instagram). Their votes will also be shown if they already voted for the polls on the generated feed.
As the website is scaling, getting their likes and votes to be queried for each question is taking a long time since there are now millions of votes. My question is how do I make this process faster? Currently, I use MySQL to store the data.
My thought is to use a cache store like Redis and store all their likes and votes for each question in this type of structure:
User_id:
likes: [question_ids]
votes: [question_ids]
where user_id is a dictionary key that contains values of array types. The feed gets loaded from the cache, for each question, we check if that question is liked or voted by the user. I'm not sure if this approach is the "best" or if there's another way of doing things. I'm wondering how Facebook, Instagram, Twitter, etc. save user interactions and how they query them.
Tables:
Question Table (simplified)
id question total_votes total_likes
Choice Table (One question has two choices)
id question_id choice votes
Voting table
id user_id choice_id
Like Table
id user_id question_id
Query to get the newest questions:
SELECT `core_question`.`id`, `core_question`.`user_id`,
`core_question`.`status`,
`core_question`.`total_votes`, `core_question`.`like_count`,
`core_question`.`comment_count`, `core_question`.`created_at`,
`core_question`.`slug`, `core_question`.`flag`,
`core_question`.`spam_flag`,
( SELECT U0.`is_liked`
FROM `core_like` U0
WHERE (U0.`question_id` = `core_question`.`id`
AND U0.`user_id` = 1)
LIMIT 1
) AS `like_selected`,
( SELECT U0.`choice_id`
FROM `core_voting` U0
INNER JOIN `core_choice` U1 ON (U0.`choice_id` = U1.`id`)
WHERE (U1.`question_id` = `core_question`.`id`
AND U0.`user_id` = 1)
LIMIT 1) AS `choice_selected`,
COUNT(CASE WHEN `oauth_following`.`follower_id` = 1
THEN `oauth_following`.`id`
ELSE NULL END ) AS `is_following`
FROM `core_question`
INNER JOIN `oauth_user` ON (`core_question`.`user_id` = `oauth_user`.`id`)
LEFT OUTER JOIN `oauth_following` ON (`oauth_user`.`id` =
`oauth_following`.`target_id`)
WHERE NOT (`core_question`.`user_id` IN (4, 5, 6, 7))
GROUP BY `core_question`.`id`
ORDER BY `core_question`.`id` DESC
I suggest these indexes:
core_question: INDEX(user_id)
oauth_following: INDEX(target_id, follower_id)
core_like: INDEX(question_id, user_id, is_liked)
core_choice: INDEX(question_id)
core_voting: INDEX(user_id, choice_id)

How to avoid table for each user

I have a rather special use case in front of me. There is to be an excel file with around a thousand entries (rows), each row represents something that the USER should pass judgment on.
Now, the entries are the same for everyone. The data that should be collected is
a) how many users like any given entry
b) what entries does any given user like
Since part of the app is already running and we have user accounts,
I thought of creating a table for each user (!) containing said excel information, adding a row for collecting the votes. I would create those tables by iteratin through the user list and creating tables like "userid_excelentries".
I don't think that's elegant. I would prefer to store the excel information only once in a table and only save the users' votes in the table "user".
The app is meant to display a table created form the excel table (I have the grid already done) and a row next to it with checkboxes. How do I structure this ? Temporary tables ? How do I store the information what each user has selected in the "user" table, since I don't know how many selections will be made a-priori ?
I had this crazy idea of actually handling the xls object through javascript, serializing it into a hash and storing that hash into a field in each user's row...but I have no clue if this is sane :o
We're facing a user count of exactly 272 - this is why I considered doing the "one table for each user" approach.
You can use 3 tables in your DB
users table
-----------
id
name
...
entries table
-------------
id
name
...
user_entries table
------------------
user_id
entry_id
user_response
To get all entries a certain user (i.e. Tom) likes you can do
select e.name
from entries e
join user_entries ue on ue.entry_id = e.id
join users u on ue.user_id = u.id
where u.name = 'tom'
and ue.user_response = 'like'
And to get the count of likes for each entry you can do
select e.name, count(ue.user_id) as likes
from entries e
join user_entries ue on ue.entry_id = e.id
where ue.user_response = 'like'
group by e.id, e.name

MySQL Query - Loading records if the owner is a friend

I've got a system on my website which is very similar to Facebook, where you can post statuses and your people can comment on your status, like it etc. This all gets inserted in the database in the following format, with child tables of the likes and comments with foreign keys set up in case the parent status gets deleted, the likes and comments get deleted with it.
I also have a friends table which contains the user ID of the user that started the friend request, the user ID of the user that has to either accept it or deny it, and the status of the record, whether it's accepted, denied or pending.
There's also a "users" table which contains the normal malarkey, such as emails, passwords etc. All records have a unique ID however, in the column "userID".
The query I have at the moment loads all statuses regardless of whether the status owner is your friend or not. The current query looks like this (I'm working in ColdFusion so ## are the variables passed to the function)
SELECT *,
(SELECT COUNT(*) FROM status_likes WHERE likeStatusID=statusID) AS StatusLikeCount,
(SELECT COUNT(*) FROM status_comments WHERE SID=statusID) AS StatusCommentCount
FROM status, users
WHERE statusOwner=userID
AND statusType='user'
ORDER BY statusDateTime DESC
LIMIT #args.indexStart#,#args.indexEnd#;
I need this query to only load statuses if the owner of the status is your friend. I can call a query to load a users friends and append a string containing the user ID's of all the friends, such as: "652,235,485,975" etc.
I tried doing an IN in the query so there was an extra line:
AND (statusOwner=#val(args.userID)# OR statusOwner IN (#usersFriendsString#))
However this brought back duplicate results and when I tried GROUP BY on the status owner, it didn't bring back records that it should have.
Any MySQL gurus out there able to help?
You should use something like that :
SELECT
s.*,
(SELECT COUNT(*) FROM status_likes WHERE likeStatusID=s.statusID) AS StatusLikeCount,
(SELECT COUNT(*) FROM status_comments WHERE SID=s.statusID) AS StatusCommentCount
FROM Users u
JOIN Friend f ON f.friendOwner = u.id
JOIN Status s ON s.statusOwner = f.id
WHERE u.id = <...>
ORDER BY s.statusDateTime DESC
You can use WHERE clause if you can't use a JOIN instruction.
Or you can use a IN instruction populated by a SELECT that retrieve all requiered status ids.

Mysql - Select user only once when subscribed to multiple categories

Good day,
Currently I am working on a project, and I am kinda stuck. It is a relative simple table where this question is about (see this photo: http://cl.ly/5M0x ).
There is a user_id collumn and a categorie_id collumn, each representing an id from another table (users and categories). Now I am trying to get the number of users within each category which is simple and can be done like:
'SELECT COUNT(uc.user_id) as total FROM xs2media_users_categories as uc GROUP by uc.categorie_id'
However what I want is that when a user has been counted for a certain category it won't be counted for another categorie where it is subscribed to. So for example if user number four is subscribed to category 2, it will increment the count of that, but not for category 3 anymore, even though he could be subscribed to that category too.
Hope this makes sence.
Thanks.
The following query picks one category for each user, and then counts the nr of users per each category.
select categorie_id
,count(*)
from (select user_id
,min(categorie_id) as categorie_id
from xs2_media_users_categories
group
by user_id
) u
group
by categorie_id;
Is this what you are looking for?

mysql query with two tables?

I have two tables:
posts(id,user_id,event_id}
events(event_id,name,date]}
I want to make a query, to retrieve all the names of the events for a particular user_id say id number 2.
In pseudo-code lets say
select all the event names from posts where user_id=2
try:
select events.name from posts, events
where posts.event_id = events.event_id and user_id = 2
You will need to have something slightly different depending on how you want results with no matches to display.
select name from events join posts using (event_id) where user_id = 2