I have 3 tables
UserPosts(id, post, userfrom_id, userto_id, date)
GroupPosts(id, post, group_id, userfrom_id, userto_id, date)
CommunityPosts(id, post, community_id, user_id, date)
i want data from all theses 3 tables with related data like community name and image for community from community table (id, name, image)
similarly group's name and image from groups table and user, userfrom, userto's name and image from users table ordered by date
Now increasing the complexity a bit more UserPost has Many
UserComments(id, userpost_id, userid, commentm date) and
UserVotes(id, userpost_id,type, date) ps:type is like/unlike
Similarly GroupPosts have GroupComments ang GroupVotes and CommunityPosts has CommunityVotes and CommunityComments. i want this data too
Now increasing the complexity a bit more it needs to be ordered by comments too(no votes, phew). What mean is if a post is 1 month old but has the a comment that was put up 5 min AGO then i needs to be listed above a post posted 1 day ago with all comments greater than 5min.
Also in the result i would like to know if the particular record is a community record or a group record or a user record
This is sort off like a facebook homepage that shows all your, your groups and friends activity. I an using PHP(cakephp), Mysql. Hope i have given all the necessary data
Sounds like your are looking for JOIN.
Related
I have a table with data relating to a user, and two important columns:
refer_count, which is updated when a new entry is made in the table with the referred_by column set to that users user_id, and referred_by which is the user_id of the of the user that referred them.
I want to select the users from the table that have the highest number of referrals after a certain date.
For example:
If there are 3 users, one of which referred the other 2 (lets say users 2 and 3), however user 2 was referred on the 2/12/14, whereas user 3 was referred on the 3/1/15.
If the cutoff is 1/12/14, then user 1 is returned with refer_count set to 2, but if the cutoff is after 2/12/14, then user 1 is returned with refer_count set to 1.
I've been thinking of how to do this, but I can't think of a way that would work. Is there a way?
This is via MySQL.
EDIT: I think I may need to provide for information.
The date registered (register_date) is used as the refer date. I need the refer_count to be updated with the number of users referred after the cutoff, however I need to get the actual user. This is for a 'top referrers' table. I can't figure out why I'm having so much trouble thinking of a way to do this.
SELECT user_id FROM usertable WHERE (referal_date BETWEEN '2014-12-2' AND CURDATE())ORDER BY refer_count DESC;
That's the rough idea.
You should look into normalizing your tables if you're keeping that all in the same table, though. It'd be better to keep referals in a seperate table.
Get the row with the maximum in refer_count with a Date condition for your referal_date such that it's after the certainDate:
SELECT user_id FROM table WHERE refer_count = (SELECT MAX(refer_count) FROM table) AND referal_date>certainDate;
Note that WHERE is before SELECT so it will not get the highest count first, but will filter with the date condition then get the highest count.
Edit: Updated query based on edited question.
So I have a table film that has various information in it, picture, title, director, ID, etc. I also have a separate table called votes. The votes table has id, filmId, value. Default value is 1, but this can change depending on who votes (weighted votes) so I am trying to call a eloquent query that will get films in order of their value sum. Based on another stackoverflow question I have come up with this.
$films = Film::join('votes', 'films.id', '=', 'votes.filmId')->orderBy(DB::raw('sum(\'votes.value\')'), 'DESC')->groupby('votes.filmId')->get();
This does not work as intended. Basically I want to go to the votes table, grab all the votes that correspond to a film id and sum up the value column and order by that. Any ideas on how this can be done?
How do social network like facebook display different content, such as photos, status, user activities onto the page, in the order it was originally posted. I have done a lot research but can't seem to find any good examples on how it's done using PHP and MYSQL.
I have include a visual example of what i mean.
I think what you mean is that the different contents are in separate tables like photos, status updates, newconnections etc. And you want the final wall to pull data from all these tables into a single wall in the same chronological order of time. So, what I will suggest is to create a new table for the wall with the following main fields :
Activity_identifier,activity_id and timestamp. Here Activity_identifier is the predefined identity of the activity such as sharing a photo (lets say 1), posting on the wall (lets say 2) etc and timestamp is the time when that activity was recorded by the user, and activity_id is the id of that activity in the corresponding table.
Everytime a new activity is created by the user, while populating the corresponding table for that activity, also record a corresponding entry in this table for wall.
Now your final query to create the wall will just have to call this new table for wall with ORDER BY TIMESTAMP DESC, then the resulting data needs to be joined with other activity tables (use Activity_identifier intelligently here) through the foreign-key activity_id to recreate the wall in the exact chronological order that the user created them.
For incremental call to the wall, maintain a timestamp of last query (lets say xtime) and every call do timestamp > xtime ... ORDER BY TIMESTAMP DESC.
Hope this helps!
Use timestamp column and keep track of each entry's insertion time in your code.
When querying data, ORDER BY timestamp column.
you can simply store a field in database which contains timestamp or creation date when specyfied content was created and while selecting it from DB just order it by mentioned creation_date :)
Use Timestamps fields in your tables (at least that's what i do) alogn with every insert (or update), with a default value of CURRENT_TIMESTAMP, this will let you sort by date (and time) of insertion with simple SQL statements
When they do the query they have an ORDER BY clause. EG:
SELECT `photos`
FROM `submissions`
ORDER BY `dateline` DESC
dateline can be stored as an integer unix time and then used with simple math to set additional parameters. EG:
$sql = "SELECT `photos`
FROM `submissions`
WHERE `dateline` >= " . (date() - 60*60*24*7) . "
ORDER BY `dateline` DESC";
This would give you only submissions from the past week.
Think of it as publishers and subscribers. Each message has a list of receivers in a junction table.
Message
------------
message_id
message_body
Message_receivers
------------
message_id
user_id
Message_photos
------------
message_id
photo
Here's how I get messages for me (user_id 1):
SELECT m.*, mp.*
FROM Message m
JOIN Message_receivers mr
ON mr.message_id = m.message_id AND mr.user_id = 1
LEFT JOIN Message_photos mp
ON mp.message_id = m.message_id
ORDER BY m.message_id DESC
You update these lists when the user posts rather than try to build the list when a user reads their news feed, since even though you may have a lot of posts, you will have more reads.
The Message_receivers records will expire and roll off. The news feed only goes back so far, though if you go to a user's page, you can see all of their posts.
I'm trying to record test/quiz scores in a database. What's the best method to do this when there might be a lot of tests and users?
These are some options I considered: should I create a new column for each quiz and row for users, or does this have its limitations? Might this be slow? Should i create a new row for each user & quiz? Should I stick to my original 'user' database and encode it in text?
Elaborating a little on the plan: JavaScript Quiz, submits score with AJAX, and a script sends it to the database. I'm new with php so i'm not sure about a good approach.
Any help would be greatly appreciated :) this is for a school science fair
I'd suggest 3 data tables in your database: students, tests, and scores.
Each student needs to have fields for an ID and whatever else (name, dob, etc) you want to record about them.
Tests should have fields for an ID and whatever else (name, date, weight, etc).
Scores should have the student ID, a test ID, and the score (any anything else).
This means you can query a student and join with the scores table to get all the student's scores. You can also join the test table these results to get labels put onto each score and calculate a grade based on scores and weight.
Alternately you can query for a test and join with the scores to get all the scores on a given test to get the class stats.
I would say create a database table, maybe one that lists all students(name, dob, student id), and then one for all tests(score, date, written by). Will only you access the db, or can your students access it too? If the latter is the case, you need to make sure the create accurate security or "views" to ensure the student can only see their own grades at a time (not everyone's).
Definitely do not create dynamic columns! (no column for each quiz). Also adding columns to user table (or generally any table) when they are not identifying the user(or generally any table item) is bad aproach...
This is pretty example of normalization, you should avoid storing any redundant rows. To do that you would create 3 tables and foreign keys to ensure scores are always referencing an existing user and quiz. E.g.:
users - id, nickname, name
quizzes - id, quizName, quizOtherData
scores - id, user_id (references users.id) , quiz_id , (ref. quizzes.id), score
And then add rows to scores table per user per quiz. Additionaly you could create UNIQUE key for columns user_id and quiz_id to disallow users to complete one quiz more times than one.
This will be fast and will not store redundant (unneeded extra) data.
To get results of quiz with id e.g. 4 and user info of people who's submitted this quiz, ordered from highest to lowest score, you would do query like:
SELECT users.*, scores.score
FROM scores RIGHT JOIN users ON(users.id=scores.user_id)
WHERE scores.quiz_id = 4
ORDER BY score DESC
Reason why I used RIGHT join here is because there might be users that didn't do this quiz, however every score always have an existing user&quiz (due to foreign keys
To get overall info of all users, quizes and scores you would do something like:
SELECT *
FROM quizzes
LEFT JOIN scores ON(quizzes.id=scores.quiz_id)
LEFT JOIN users ON(users.id=scores.user_id)
ORDER BY quizzes.id DESC, scores.score DESC, users.name ASC
BTW: If you are new to PHP (or anybody reading this), use PHP's PDO interface to communicate with your database :) AVOID functions like mysql_query, at least use mysqli_query, but for portability I would recommend stay with PDO.
Hi I have a question regarding a method to prevent second voting in a website where people can vote up or vote down a comment. Like Stackoverflow!! :)
The question is how I can keep track of whether a comment has already been voted by a logged in user. Lets assume this is for a online ecommerce store with reviews on products. Here's what I think:
All reviews data is stored in a table called 'reviews'
Field names: review_id, product_id, user_id, title, description, time_created, up_votes, down_votes, up_voters, down_voters
up_votes and down_votes contain the number of votes voting it up or down
up_voters and down_voters contain the user_id of the people who voted up or down in the format 1101.1102.1103 for users with user_id 1101, 1102 and 1103.
When a person clicks on the up vote button, the system will check if the current user's user_id matches anyone in up_voters. An explode function will turn 1101.1102.1103 into an array and in_array() will be used to check if the user has already voted.
Is there a better way to go about doing this?
That table will give you nightmares down the line. Just think of a hit product with 1K up_voters, your field will be 10K*4 characters long! Not just that, it will hinder your ability to make reports and study the data etc.
I don't know much about your needs but from what I can see in your table, I'd suggest the below.
review
user_id, product_id, type_of_vote, title, description, time_created
Use above table and use user_id, product_id as the key
OR
review
review_id, product_id, title, description, time_created
vote
review_id, user_id, type_of_vote
There are n number of ways to design tables for this. If it is an Operational Data Store(ODS) then you might want to normalize your design. If it's a warehouse then you may consider first table I mentioned above.