I am currently developing an article driven site and would like to know the best way to track page hits so I can display something along the lines of "Most Viewed" or "Most Popular Articles". I display my articles through a $_GET on a single PHP page (e.g article.php?id=2). I read somewhere that an INSERT INTO was the way to go and I tried to do:
$page_views = $conn->query("INSERT INTO blog_posts (views) VALUES (views = views+1");
Alas, this did not work.
In summary I want to be able to:
Add 1 to the number of page views on an specific id for each time someone lands on the page (e.g articles.php?id=3) not just articles.php
Thanks in advance.
(Sorry if I haven't made this clear enough. If you want anything clarifying just ask.)
Do you intend to keep a separate table for the counts? If so,
|page_views |
|blog_id|count|
+-------+-----+
| 1 | 12 |
| 2 | 33 |
with blog_id being a primay key with unique enforced
you could use on duplicate key to create a row if it doesn't exist and update the count if it does
("INSERT INTO page_views (blog_id,count) VALUES ($blog_id,1) ON DUPLICATE KEY UPDATE count = count + 1")
Why don't you try with update statement:
"UPDATE blog_posts SET views = views+1 WHERE id = $id"
Your insert statement will add a new row in the database, what probably is not what you want.
Use an update query to increment the counter.
UPDATE blog_posts SET views = views+1 WHERE id = 'SOME NUMBER'
Where your each row in the blog_posts table has a numberic views field and an id.
SQL Fiddle:
http://sqlfiddle.com/#!2/0915b/1
Related
I am making a site which allows admins to basically add points for a user.
At this point in time, I have a table, where id_child is unique, and id_points changes. So a constant stream of id_points can come in, however, it will only show the latest id_points, not the total.
I am wondering how I could go about creating a PHP script that could add all of those together.
From the image, the idea is that I want all id_points values added together to give a total, and this is for the same id_child
Use SQL sum() funciton:
select sum(id_points) from table `table_name` where `id_child` = 1
Hope i understood right.
First if you want to show only the latest points added you have to create another table #__points where you will keep every new change of points.
You need 3 columns id as PRIMARY and AUTO_INCRENMENT , pts and user_id . user_id will be FK to id_child.
So when you want to add a new record :
INSERT INTO `#__points` (pts,user_id) VALUES ("$pts",$id)
When you want to select last inserted value for each admin :
SELECT * from `#__points` where user_id=$id ORDER BY id ASC LIMIT 1
My question is a little bit confusing, i understand that my question may sound similar to other questions here. I have a form that is numbered and increase by 1 depending what is the last value in the database.
For example in the database:
ID | ApplicationNumber
1 | 1
2 | 2
So if the user will generate another form it will display as: Application Number 3. And it will be save in the database as application number 3. But what if there are two users who will submit the form at the same time? Both are filling up the form numbered as: Application Number 3 and before my INSERT INTOi perform the query of looking the last value in the database so i can +1 to the value of Application Number value before submitting it to the database. I let two users submit the form at the same time and what i received in the database is like this:
ID | ApplicationNumber
1 | 1
2 | 2
3 | 3
4 | 3
My query for getting the last value and BEFORE inserting something to the database:
$query = mysqli_query($con,"SELECT table1.ApplicationNumber FROM table1 INNER JOIN table2 ON table1.AdminID = table2.AdminID AND table2.Username = '$user' ORDER BY table1.ApplicationNumber DESC LIMIT 1");
while($row = mysqli_fetch_array($query)) {
$aNumber = $row['ApplicationNumber'] + 1;
}
If I'm getting you right there are few straightforward options from the database point of view:
Use autoincrement for the ApplicationNumber column in mysql
Create Unique-key constraint for this column and handle this error somehow
Also you can just LOCK the table before select, so you have exclusive access to the data. Beware, you should especially care for unlock and understand that other users won't be able to use this table, while lock in effect.
I am making a basic CMS system which allows for page edits by registered users.
I wish to store a list of users who have submitted some page content to each a specific page. In my database table for pages, I have a column called contributed, and in there I want to have all the user id’s of each user who contributed to each page, separated with a common. Looking something like this ...
Page Name | Author | Comments | Contributed
---------------------------------------------------------------
Home | 1 | 0 |1, 2, 3, 4
About | 1 | 0 |1, 3, 4, 7, 9
Contact | 2 | 0 |2, 4
Download | 8 | 0 |8
Using MySql, how can I write an update query that appends another user id to this column when a user makes a contribution instead of updating the entire row, removing the ids of those who have previously contributed?
For this, it would be best to create some sort of history table. Example:
**page_history**
id
page_id //ID of the page
user_id //ID of the user making the change
date //Date and time of the change
from //The old content
to //The changed content
Then you'd insert a new row into page_history every time a user edits a page. Note: You should read up on the concept of Database Normalization.
I might end up doing this on one level up - without any knowledge of size of your CMS:
CREATE TABLE test(pageid INT, contributed VARCHAR(1024));
INSERT INTO test(pageid, contributed) VALUES (1, "kala");
UPDATE test SET contributed = CONCAT((SELECT contributed FROM (SELECT * FROM test) as a WHERE pageid = 1),',','new_user_name') WHERE pageid = 1;
For SELECT * FROM test there is good description at
You can't specify target table for update in FROM clause
I'm interesting in creating from scratch such feature to learn, I'm having a hard time understanding and being able to plan such structure. Most programmers from what I've seen
check if someone has already rated the comment or post by their IP address, I dislike that specially due to the fact that each user must be logged in to vote, so why not check the
user iD instead of iP. I also tend to choose performance instead of looks so could someone help me understand how to begin to accomplish this. I've read and searched many posts
on SO(StackOverflow) yet they're not too comprehensive for me. I also read somewhere to have a UNIQUE KEY constraint to only allow one vote, is that correct?
Some suggestions on a table structure and maybe how to design would be greatly appreciated.
I'm confused with such structure, the following tables is what I've got so far.
Posts:
post_iD | message | uid_fk(user id) | voteUp | voteDown
PostsRateSystem:
rate_iD | rate_user_iD(uid_fk from posts table) |
Do I even need a second table to keep track of who has rated.
if(isset($_POST['plus']) && isset($_POST['minus'])){
$plus = $_POST['plus'];
$minus = $_POST['minus'];
$row = insertRate($post_iD, $plus, $minus);
}
<form method="post" action="">
Thumbs Up
Thumbs Down
function insertRate($post_iD, $plus, $minus)
{
if($plus)
{
$sth = $this->db->prepare("UPDATE posts SET voteUp = 1 WHERE post_iD = :postiD");
$sth->execute(array('postiD' => $post_iD));
}
if($minus)
{
$sth = $this->db->prepare("UPDATE posts SET voteDown = 1 WHERE post_iD = :postiD");
$sth->execute(array('postiD' => $post_iD));
}
}
If all users can rate each post once, you'll have to have a third table (votes) that has a userid, a postid and a rating value (either 1 or -1). In that table, you should make the combination of userid and postid unique, because a user is only allowed one vote per post.
To get the total number of votes for a post, you can just sum those values:
SELECT SUM(votes.value) FROM votes WHERE postid = 10
Now, each upvote is counted as one, and each downvote as minus one, because those are the actual values stored.
To save a vote, you'll have to try to update the table first, because the logged in user can already have a vote. If updating fails, probably due to no vote already exists, you can insert a vote for the user for that post.
To speed up things, you can also increment or decrement a vote counter in the post table itself. That one doesn't keep track of all users, but it does keep track of the total score. That way, you don't have to query the sum for each page view of a vote. Keep in mind though, that if a use changes their upvote to a downvote, you'll have to subtract 2 from that score and vice versa. Alternatively, you can use the SELECT SUM query to calculate the votes and store it in the post, after each change to the votes of a post. So after voting for post 10, do this:
UPDATE posts
SET score = (SELECT SUM(value) FROM votes WHERE postid = 10)
WHERE postid = 10
i am using this code so i can count the number of comments for each article
SELECT *, COUNT(comment_id) as count
FROM article_comments
WHERE article_id =colname
GROUP BY article_id
this is what my comment table look like
http://i54.tinypic.com/2cdu3dk.png
i want to save these number in another table (the articles table.. each number next to it's article ) like this
http://i54.tinypic.com/2dgm82u.png
and when the user enter a comment..the number change automatically
someone help me with the code
or if there is another way to do this
i know it's a long question
but i have been trying to solve this for like..forever
thanx
You could set a TRIGGER that updates the comment count table every time a comment is added. Or you could simply add the UPDATE query right after the INSERT query in your comment page.
You probably do not need a lookup table. 1 article has many comments. Therefore, structure your comments table something like this (add an article field);
id | article | content
-------------------------
1 | 1 | Comment 1 for article 1.
2 | 1 | Comment 2 for article 1.
3 | 2 | Comment 3 for article 2.
When displaying your article, list comments using the following query;
SELECT a.id, a.content FROM articles a WHERE a.article = :myArticleId
When creating a new comment:
INSERT INTO comments (article, content) VALUES (:currentArticleId, :content)
UPDATE article SET commentCount = commentCount + 1 WHERE article = :currentArticleId
The articles table will look something like this;
id | commentCount | content
------------------------------
1 | 0 | Article with 0 comments.
2 | 3 | Article with 3 comments.
This requires some work on your part, but it has more benefits than drawbacks.
Your proposed solution has 2 large drawbacks;
COUNT() in SQL does not scale very well and can be slow, normally it can be avoided.
The lookup table adds unnecessary complexity to your application.
Triggers should also always be avoided. They create "magic" conditions - your database can be changed without you knowing about it. Triggers are often more difficult to change than code too.
$query = mysql_query("SELECT * FROM article_comments WHERE article_id =".$youarticleId);
//the number of comments is :
$number_Of_Comments = mysql_num_rows($query);
//save it to another table
$query2 = mysql_query("UPDATE yourTable set numberOfComments =".$number_Of_Comments);
on saving comments, try to:
update table_where_you_count_the_comments set number_of_comments = number_of_comments +1 where article_id = theID limit 1;
or look for mysql triggers.
you're asking the sql server to select everything and the count id at the same time, use one of them and give it a where close, and Bingo!