Most populated artcles - php

I have articles and each of them has views. And in sidebar i display the most visited articles. All is working, but with order is problem. For example i have 4 articles. 1 article has 10 views, 2 - 7 views, 3 - 6 views, 4 - 3 views. And order is
1) 1 article - 10
2) 2 article - 7
3) 3 article - 6
4) 4 article - 3
So we can see that all is ok. But when i add one more artilce and it has 1 views order change and 5th artilce goes to top but why. It has lower views then another articles? And when 5th article get 10 views, all is ok and order restored. But why just when order resores when last artilce has more then 10 views?
<?php
$dbname="php";
$dbhost="localhost";
$dbusername="root";
$dbuserpassword="";
$optins= array(PDO::MYSQL_ATTR_INIT_COMMAND=>'set NAMES utf8');
try{
$db= new PDO("mysql:host={$dbhost};dbname={$dbname};chartset=utf8",
$dbusername,$dbuserpassword,$optins);
} catch (PDOException $ex) {
die("Fail to connect".$ex->getMessage());
}
// all post
$sql = "select * from tbl_blog order by page_view desc limit 5";
$data=$db->prepare($sql);
$data->execute();
$allpost=$data->fetchAll();
// Single Post
CREATE TABLE:
CREATE TABLE tbl_blog (
id int(11) NOT NULL,
blog_title text NOT NULL,
description text NOT NULL,
content text NOT NULL,
page_view varchar(10) NOT NULL,
category text NOT NULL,
img varchar(225) NOT NULL,
sub_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE = InnoDB DEFAULT CHARSET = utf8

For me, it's seems that the alphabetic order take control of the page_view attribute.
If your page_view attribute is define as varchar, it will be ordered like a character, for exemple:
"3"
"2"
"12"
"11"
"10"
"1".
Check to put the page_view attribute as integer, to have
1
2
3
10
11
12
Hope this help

The problem is the datatype of page_view is VARCHAR(10), so it gets sorted as strings, not as numbers.
Change the data type to a numeric type (e.g. INTEGER) and it'll sort correctly.

Related

PHP Mysql always NEED to return 5 rows even 3rows present in table

Hi i need 5 rows count always in Mysql select query
I My current output is
my query
----------------------
$query = mysql_query("select * from table_name where MOBILE='$mobile_no' order by ID LIMIT 5 ");
----------------------
Result
----------------------
ARUN - 987654321
VINO - 987654321
RAJA - 987654321
-------------------
But I need like this (Need to return empty rows)
----------------------
ARUN - 987654321
VINO - 987654321
RAJA - 987654321
0 - 0
0 - 0
-------------------
So that I can create html table row (always 5 rows) text box with empty value inside the while loop ----- while($row=mysql_fetch_array($query))
You can use a loop in php and a counter in the loop. If the count is less then 5, then you fill the text box with nothing. It will give you something like that
$count = 0;
while($row=mysql_fetch_array($query)) {
// Fill your text box
$count+=1;
}
for($i=count; $i <= 5; $i++) {
// Fill your text box with empty string or whatever.
}
Since you requested a sql solution here it is: (but I do not recommend using it)
SELECT *
FROM (SELECT id, column1
FROM table_name
WHERE mobile = '$mobile_no'
UNION ALL
SELECT NULL, NULL FROM DUAL
UNION ALL
SELECT NULL, NULL FROM DUAL
UNION ALL
SELECT NULL, NULL FROM DUAL
UNION ALL
SELECT NULL, NULL FROM DUAL
UNION ALL
SELECT NULL, NULL FROM DUAL)
AS tab
order by tab.ID LIMIT 5
but you need to explicitly select all the columns from your table and in the select statements add as many NULL columns as you selected in your main statement. I didn't test it since I don't know your columns
simply add 2 more textboxes in html page. and not send any value or send null values in your database

Retrieve from MySQL "most clicked items in the past 6 hours"?

When a user clicks on a link, new data with the following format is stored in a MySQL_DB table called tracking_table:
id url title clicktime
1 http://1.com title 1 2014-12-07 21:33:53
2 http://2.com title 2 2014-12-07 21:34:03
3 http://1.com title 1 2014-12-07 19:30:00
4 http://3.com title 3 2014-12-07 18:38:47
5 http://1.com title 1 2014-12-07 22:23:54
6 http://2.com title 2 2014-12-07 20:17:20
7 http://7.com title 7 2014-12-07 10:20:12
8 http://1.com title 1 2014-12-07 21:38:03
How could I display (in PHP) in descending order the top 5 titles that were clicked on over the past 6 hours? Given the data recorded so far (supposing that NOW is 2014-12-07 22.24.00), my result should look like:
# url no. of clicks title
1 http://1.com 4 title 1
2 http://2.com 2 title 2
3 http://3.com 1 title 3
I have created the DB using this command:
CREATE TABLE `tracking_table` (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
url varchar(255) DEFAULT NULL,
title varchar(255) DEFAULT NULL,
clicktime timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
Any help would be much appreciated!
You should group the clicks by url and title, count them and then use a limit clause to retrieve only the top 5:
SELECT url, title, COUNT(*)
FROM tracking_table
WHERE DATE_DIFF (NOW(), clicktime) * 24 <= 6
GROUP BY url, title
ORDER BY 3 DESC
LIMIT 5
I would suggest the following:
select tt.title, count(*)
from tracking_table tt
where clicktime >= date_sub(now(), interval - 6 hours)
group by title
order by count(*) desc
limit 5;
This is similar to Mueinik's answer, with one important exception: the where clause. First, this calculation should work and second clicktime is not an argument to a function. The latter means that an index on clicktime could be used. (There is not one in the table definition, but it might be a good idea for this type of query.)

need help in search [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
As per my system i need to search brand based on category and subcategory.
Brand table like this
id brandname categoryid subcategoryid
1 xys 1,2,3 1,5,6
Now when i search i select category then as per category all subcategory come now i select subcategory now need to show all the brand based on that category and subcategory.
My brand table look like this because same brand have multiple category and subcategory.Please help me to solve this problem
Given your database design, you can do that like this:
SELECT * FROM mytable WHERE
FIND_IN_SET('5', categoryid) > 0 AND FIND_IN_SET('3', subcategoryid) > 0;
This will find all items from category 5 and subcategory 3.
SELECT * FROM mytable WHERE
FIND_IN_SET('5', categoryid) > 0 AND (
FIND_IN_SET('3', subcategoryid) > 0
OR
FIND_IN_SET('9', subcategoryid) > 0
);
The above will find items in category 5, subcategories 3 and 9. Of course you can also restrict to items that are in both categories, by using AND instead of OR.
But all this is needlessly expensive. You would do better by having a table for brand names, and other tables for category and subcategory IDs, and links, like this:
// This is an article. Many-to-one relation with brands.
CREATE TABLE articles
(
id integer primary key not null auto_increment,
name varchar(...),
brand_id integer,
//, other data
);
CREATE TABLE brands
(
id integer primary key not null auto_increment,
name varchar(...)
//, other data
);
// Categories. Many-to-Many relationship with articles.
CREATE TABLE categories
(
id integer primary key not null auto_increment,
name varchar(...)
//, other data
);
// Subcategories. These are independent from categories, which
// may be right or wrong, depending. Being independent, we do not
// store here parent_category_id.
CREATE TABLE subcategories
(
id integer primary key not null auto_increment,
name varchar(...)
//, other data
);
// Many to many relationship between articles and categories
CREATE TABLE mtm_article_in_category
(
article_id integer not null,
category_id integer not null
);
CREATE TABLE mtm_article_in_subcategory
(
article_id integer not null,
subcategory_id integer not null
);
// Add article 5 to categories 25, 37 and 119:
INSERT IGNORE INTO mtm_article_in_category VALUES ( 5, 25 ), ( 5, 37 ), ( 5, 119 );
// Remove article 18 from subcategory 92
DELETE FROM mtm_article_in_category WHERE article_id = 18 AND subcategory_id = 92;
This way you can run much faster queries, and not have problems such as the inability to assign an article to more than "so many" categories (e.g. 50); nor the headaches if you wanted to move an article from a category to another, that with your current design would be next to impossible.
My search like this at first i chose category the all the subcategory
come based on category.Then when i chose subcategory all the brand
based on that category and subcategory come.Now i add one brand name
one time with multiple category and multiple subcategory.
I have to say, "Oh my God". To be able to "select all the subcategories" /now/, you would have to transform this
category subcategory
4,5 1,7,9,19
5 7,9,11
in
5 1
5 7
5 9
5 19
5 7
5 9
5 11
then run a DISTINCT, and finally use the subcategories as an INNER JOIN based on FIND_IN_SET.
The first step ("explode" a CSV row) can be done like this: http://www.marcogoncalves.com/2011/03/mysql-split-column-string-into-rows/ ... and as you can see it is all but trivial.
I expect that currently you are doing the splitting in PHP.
After doing that, the INNER JOIN is awfully expensive.
We are throwing good money after bad. Your current database design does not allow to do what you want, easily. The simplest way would be:
// My search like this at first i chose category the all the subcategory
// come based on category.
$query = "SELECT subcategoryid FROM mytable WHERE FIND_IN_SET(:mycategory, categoryid) > 0;";
// and run the query.
$subcategories = array();
while($tuple = sql_fetch_tuple($exec))
{
// Explode "1,2,3" into array {1, 2, 3}. Merge into subcategories removing
// duplicates. Rinse. Repeat.
$subcategories = array_unique(array_merge($subcategories, explode(',', $tuple['subcategoryid'])));
}
sql_free($exec);
// Now we have an array of subcategories.
// Then when i chose subcategory all the brand
// based on that category and subcategory come.
$subcat_query = array();
foreach($subcategories as $subcategory)
$subcat_query[] = "FIND_IN_SET('$subcategory', subcategoryid)";
$subcat_query_sql = implode(' OR ', $subcat_query);
$query = "SELECT DISTINCT brand FROM mytable WHERE FIND_IN_SET(:cat, categoryid) AND ( $subcat_query_sql );";
// And here we get all brands. It is wise to save $subcat_query_sql in _SESSION.
// Next search will be:
// >Now i add one brand name
// > one time with multiple category and multiple subcategory.
// Note that you've subtly moved the target once more, now the 'category' has become "multiple".
$brands_arr[] = array();
foreach($brands as $brand)
$brands_arr[] = "'" . sql_escape($brand) . "'";
$brands_sql = implode(',', $brands_arr);
// The cost of this $query is estimated as a significant percentage of U.S. gross internal product, so it ought to be cleared with the FED.
$query = "SELECT * FROM mytable WHERE brand IN ($brands_sql) AND FIND_IN_SET(:cat, categoryid) AND ( $subcat_query_sql );";
It is also possible that the above query will return nothing at all. Suppose that you looked for subcategory 5 and category 12. By your request, getting "all subcategories" and "all categories" might return also brand 6 and subcategory 9. Then these two rows come out,
Marlboro 5 12
Lucky 6 9
and the user selects "Marlboro 6 12". He won't get anything - no rows will match that query.
I am afraid that the user interface and workflow/use case needs looking into, too.

PHP & MySQL Update Database Problems

I'm trying to change my rating system which only used one table before but now I'm changing it to use multiple tables and I really dont no how to
update or insert a new rating into the database and was wondering how to do this using my MySQL tables structure?
Also how do I do this by adapting the new code to my current PHP code which I want to change which is listed below.
First let me explain what my tables do they hold the information when students rate there own teachers I listed what the tables will hold in the
examples below to give you a better understanding of what I'm trying to do. Students are only allowed to rate there teachers once.
I provided the two MySQL tables that should be updated which are listed below.
My MySQL tables
CREATE TABLE teachers_grades (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
grade_id INT UNSIGNED NOT NULL,
teachers_id INT UNSIGNED NOT NULL,
student_id INT UNSIGNED NOT NULL,
date_created DATETIME NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE grades (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
letter_grade VARCHAR(2) NOT NULL,
grade_points FLOAT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
What the database will hold.
teachers_grades
id grade_id teachers_id student_id date_created
1 3 2 32 2010-01-23 04:24:51
2 1 32 3 2010-01-23 12:13:58
3 2 32 103 2010-01-23 12:24:45
grades
id letter_grade points
1 A+ 10
2 D 3
3 B 5
Here is the old PHP code.
// function to insert rating
function rate(){
$text = strip_tags($_GET['rating']);
$update = "update vote set counter = counter + 1, value = value + ".$_GET['rating']."";
$result = mysql_query($update);
if(mysql_affected_rows() == 0){
$insert = "insert into vote (counter,value) values ('1','".$_GET['rating']."')";
$result = mysql_query($insert);
}
}
Old table.
CREATE TABLE vote (
`counter` int(8) NOT NULL default '0',
`value` int(8) NOT NULL default '0'
);
first , do mysql_escape_string to the parametrs when inserting like :
mysql_real_escape_string($_GET['rating']);
second
you need to get all parameters (from GET or POST) and insert it to the db ,
the teacher_id ....
now i only see the rating.
Your old table was bit confusing as it seems like it only rates 1 teacher or teachers as a whole.
Now it seems like your new design process requires you to:
- store rating and averages of teachers
- track historical ratings from students
rating table should look something like
Table: rating
rating_id student_id teacher_id grade_id date_created
1 101 21 1 2010-01-23 04:24:51
2 102 21 1 2010-01-23 04:26:51
3 102 22 2 2010-01-23 04:28:51
4 103 24 1 2010-01-23 04:44:51
Your code usage:
$rating_value = $_GET['rating']; // Remember to sanitize your inputs
$student_id = $_GET['student_id'];
$teacher_id = $_GET['teacher_id'];
rate_a_teacher($teacher_id, $student_id, $rating_value);
Your method:
function rate_a_teacher($teacher_id, $student_id, $rating_value)
{
// Find the corrosponding to specified rating value
$grade_id = find_grade_id($rating_value); //TODO
$sql = "
INSERT INTO rating
('student_id', 'teacher_id', 'grade_id', 'date_created')
VALUE
($student_id, $teacher_id, $grade_id, NOW);
";
mysql_query($sql);
}
I skipped implementation for find_grade_id() for you to fill it in yourself.
The purpose of splitting your calcualted values to individual records is so that you can start do interesting reports,
like such:
Find average rating value of each teacher for the past 3 months:
SELECT teacher_id, (SUM(points)/COUNT(rating_id)) AS average_score
FROM rating
LEFT JOIN grades ON grades.id = rating.grade_id
WHERE date_created > SUBDATE(NOW(), INTERVAL 3 MONTH)
GROUP BY teacher_id

SQL Query, within php

I currently have a query
$query = "SELECT * FROM routes ORDER
BY id DESC LIMIT 8;";
And that works all wonderfully.
I have table columns
id int(10)
name varchar(45)
base varchar(16)
econ int(6)
location varchar(12)
x int(2)
y int(2)
galaxy int(2)
planet int(2)
comment varchar(100)
ipaddress varchar(45)
and on the page when this segment of php is called i will have
the econ,X,Y,Galaxy,and planet of another entry
then i want to display the entry is the database(like i do at the moment) BUT
i want a new column to be displayed that is not in the DB, this new column is to be the output of a calculation..
the calculation is to be
Sqrt(min. Economy) x ( 1 + Sqrt(Distance)/75 + Sqrt(Players)/10 )
Sqrt(88) x ( 1 + Sqrt(23)/75 + Sqrt(23)/10 ) = 15 cred./h
players is another variable that is already available in my page
Distance is a function of the 2 galaxys unless there the same when its a function of the 2 x's and y's unless there the same and then its a function of the 2 planet integers
here is the page i talk of..i will add a new button to compare.. thats the new function that i want to compare the given value with existing values.
http://www.teamdelta.byethost12.com/trade/postroute2.php
You can just calculate in your query like this:
$query = "SELECT (Sqrt(min. Economy) x ( 1 + Sqrt(Distance)/75 + Sqrt(Players)/10 ) Sqrt(88) x ( 1 + Sqrt(23)/75 + Sqrt(23)/10 ) = 15 cred./h) as `Distance`, * FROM routes ORDER BY id DESC LIMIT 8;";
Use as for naming your calculation so its become a column and use * to get the other fields.
After the query you store the results into an array. You could parse the array adding an item containing the calculation that you wrote.
If you want more details you should past here the array
--
dam

Categories