I am trying to sort the information given to me by the API of an engineering journal. I have extracted the following information into a table:
ID (integer),
Journal Entry Name (Text),
Description (Text),
Page Length (integer),
Has Media (boolean)
Each "Journal Entry" has only one ID associated with it. Each ID also has other characteristics that are not returned by the API but that I want to use to sort. They are:
Category (Things like Econ, Math, Biology. Each ID can have more than one category)
Boolean values (Things like requiring special subscriptions)
I have created a second table in the following format:
ID (integer),
Category (text),
Boolean1 (bool),
Boolean2 (bool),
Boolean3 (bool)
Since each ID can have more than one category, when this occurs another row is added to this table. The idea being that any given row only has one ID and one category in it.
What I want to do is this:
Be able to find the top ten categories when it comes to
Highest Journal Entry (ID) count
Highest Total Page Length
Highest Journal Entry count where the "Has Media" boolean is true
Create a means of navigating like "pagination" where each page shows the nth results of the aforementioned top ten.
So if I chose to Highest Journal Entry count method, the first page would be show IDs, Names, and Descriptions of all the Journal entries in the category with the highest count.
My plan has been to create a new table where the numbers one through ten are in the first column, and then populate the second column with the top ten categories. Then I can use a process similar to pagination in which the nth page only shows the values with the corresponding category from the original value. However I can't seem to be able to make this top ten list/matrix, nor do I know if it there is a better way.
Unfortunately I am not a MySQL or PHP coder by trade, and have only gotten this far by lots and lots of googling. I have been completely unable to find any guides for a navigation method like the one I want. And since I don't know the proper terminology, I am just trying random google searches at this point.
Is this the best way to go about it? Or would it be better to create a third table of some sort? Is there perhaps an easier way to do this with something that can use the PHP and MySQL code I already wrote?
Not sure I really understand what you're going for here, but my best guess is that you probably want to combine your two initial tables and have category be a set rather than an individual term so you can have a single entry per unique ID.
Then you'd just need to write calls for each of your top ten finds as needed. Since each id can have an unknown number of categories I would start with a limit of 10 and then process the returns starting with the top match, grab its categories, if there are more than 10 grab the first 10, if there are less than 10 grab what there are, update the amount you're looking for (if there were 4 then you're now looking for 6), and move on to the next best match.
Maybe something like this:
categories = null;
$delimeter = ',';
$count = 1;
$top10 = array();
$result = mysql_query("
SELECT *
FROM table_name
ORDER BY page_length DESC
LIMIT 10");
while($row = mysql_fetch_array($result) && $count <=10)
{
$categories = $row['categories'];
$id = $row['id'];
$splitcontents = explode($delimeter, $catagories);
foreach($splitcontents as $category){
if (!in_array($catagory,$top10)){
$top10[$count] = array(
'category'=>$category,
'journal_id'=>$id
);
$count++;
}
}
}
Related
I'm using MySQL and Php.
Here's the thing : I'm building a forum, with topics and posts.
Posts are displayed in a topic in different pages (let's say 10 posts/page).
My question is : if I ask to see a specific post in a topic, how can I know the page where the post is displayed ? (With the purpose to display the page required)
Should I calculate the number of pages then check each group of items of all possible pages or something like that ?
Thx for your help !
You could use Google Custom Search and let Google do all the hard work. I hear they're quite good for searching websites.
If you want something a little fancier you can pay for Google Site Search.
if your site is small and you want to try a really really simple solution why don't you explore MySQL Fulltext search?
That said the field, fields to search must be a Fulltext index. So you can grab a pair of text fields and some varchar fields and jointhem all in a Fulltex Index.
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database' WITH QUERY EXPANSION);
But go and have a better look at MySQL manual!
Ok, I was eating and then... THE IDEA.
I guess a simple way to doing this is to count the number of items before the needed one (with ID or, in a better way, with Timestamps cause posts are ordered with those), and then calculate how many pages it takes.
Meaning, for example, if pages display 10 items, we have 24 items before our targeted one : ceil(24/10) = 3 item will be in page 3 !
Very simple when we think of it.
#Get the page displaying the selected item
#Step 1 : calculate how many items are before the selected one
$nbr_of_items = SELECT COUNT(post_id) FROM posts WHERE post_topic_id = :topic_id AND post_timestamp < :timestamp_of_selected_item
#Step 2 : do simple maths
$calcul = ceil($nbr_of_items / $nbr_of_items_displayed_in_a_page);
For example, we have 24 items before the selected one and pages display 10 items :
$calcul = ceil(24 / 10) = 3
Of course it could be updated (what if an other post has the same timestamp, etc) but it's a good start.
I'm trying to insert diferent numebers (like "10 11 12") into a MySQL field (the numbers come from PHP), but when I do the query, the field only gets the first number.
For example, I do:
UPDATE profile SET subcategory = '10 11 12' WHERE userId = 1 LIMIT 1
And the DB just registers '10'.
Any way to do it?
This happen because you're updating a number, probably an integer, so mysql do the job just for the first number.
If you do this:
UPDATE profile SET subcategory = 10 WHERE userId = 1 LIMIT 1
UPDATE profile SET subcategory = 11 WHERE userId = 1 LIMIT 1
UPDATE profile SET subcategory = 12 WHERE userId = 1 LIMIT 1
You'll just update the category with the third value (12).
I suggest you a user belonging to multiple subcategories so you'll have to create another table. Eg: a table called subcategories with at least two fields: userId and subcategoryId. And then you could do something like this:
DELETE FROM subcategories WHERE userId=1
INSERT INTO subcategories (userId, subcategory) VALUES (1,10)
INSERT INTO subcategories (userId, subcategory) VALUES (1,11)
INSERT INTO subcategories (userId, subcategory) VALUES (1,12)
The first line (delete) is used just to update the user's subcategories, first you delete all older subcategories for the user and then you insert the new ones. In PHP you could use a foreach() to automatize the insertion of multiple values.
You could also have a non unique userId in the table profiles with an entry per user subcategory but it will complicate things.
I hope it could help you
From your problem I guess that the type of your subcategory is integer. What happens when you put string? It is converted. The converter convert it to first proper integer which is 10 space after 10 is considered as string.
What can solve your problem?
Chance db structure and depend on relations.
(bad idea) change the type to varchar for example and then insert will be done(DONT DO IT)
Do multiple updates(it really depends on db structure)
This very much depends on the problem you are trying to solve.
If you are just trying to store a small number of numbers then using the php join and split functions to take a list of numbers and convert to and from a string and store that in a VARCHAR.
A better way to solve the problem would be to understand the layout of your data. Try having a table that links profiles to subcategories. Two columns, one for the profile ID and one for the Subcategory ID. You might find having a search for database normalisation informative.
This presentation looks relatively informative: http://www.sqa.org.uk/e-learning/MDBS01CD/page_26.htm
I have single table where i put all the content. Each row is one post. I want to be able to manipulate order of posts so that i can push some of those to the top or bottom...
Also, each post belongs to certain category. (i believe that that additional parameter makes difference when ordering posts within certain category)
Please, give me some hints/code patterns how would you do it?
p.s. i don't want to add new tables, make more relations, i want it as simple as possible...
I would personally accomplish this by adding a sort_index field to the table with a default value of something like 100. You can then push posts down by decreasing their sort order, or push them to the top by increasing it. By starting with a specific number, you are establishing a baseline for default sorting of posts.
SELECT * FROM `posts` ORDER BY sort_index DESC, date_posted DESC
This would use ensure posts with the same sort index get a secondary sorting based on the date they were posted.
It also allows you to then easily automate making the posts fall down in the rankings over time with a small script setup as a cron to decrease the sort index of posts every so often until they hit the default value.
Let's say you have a table with the following columns:
id
post
category
You can add a new integer column called rank. Using the new rank column you can order your posts like this:
SELECT `post` from tblPosts order by category, rank;
Now you can order your posts by assigning a rank to them. In the above example smaller numbers will be listed at the top and larger ones at the bottom.
I'm trying to create a web index. Every advertiser in my database will be able to appear on a few categories, so I've added a categorys column, and in that column I'll store the categories separated by "," so it will look like:
1,3,5
The problem is that I have no idea how I'm supposed to select all of the advertisers in a certain category, like: mysql_query("SELECT * FROM advertisers WHERE category = ??");
If categories is another database table, you shouldn't use a plain-text field like that. Create a "pivot table" for the purpose, something like advertisers_categories that links the two tables together. With setup, you could do a query like:
SELECT A.* FROM advertisers AS A
JOIN advertisers_categories AS AC ON AC.advertiser_id = A.id
WHERE AC.category_id = 12;
The schema of advertisers_categories would look something like this:
# advertisers_categories
# --> id INT
# --> advertiser_id INT
# --> category_id INT
You should design your database in another way. Take a look at Atomicity.
Short: You should not store your value in the form of 1,3,5.
I won't give you an answer because if you starting you use it this way now, you going to run into much more severe problems later. No offense :)
It's not possible having comma-separated values to do this strictly in an SQL query. You could return every row and have a PHP script which goes through each row, using explode($row,',') and then if(in_array($exploded_row,'CATEGORY')) to check for the existence of the category.
The more common solution is to restructure your database. You're thinking too two-dimensionally. You're looking for the Many to Many Data Model
advertisers
-----------
id
name
etc.
categories
----------
id
name
etc.
ad_cat
------
advertiser_id
category_id
So ad_cat will have at least one (usually more) entry per advertiser and at least one (usually more) entry per category, and every entry in ad_cat will link one advertiser to one category.
The SQL query then involves grabbing every line from ad_cat with the desired category_id(s) and searching for an advertiser whose id is in the resulting query's output.
Your implementation as-is will make it difficult and taxing on your server's resources to do what you want.
I'd recommend creating a table that relates advertisers to categories and then querying on that table given a category id value to obtain the advertisers that are in that category.
That is a very wrong way to define categories, because your array of values cannot be normalized.
Instead, define another table called CATEGORIES, and use a JOIN-table to match CATEGORIES with ADVERTIZERS.
Only then you will be able to properly select it.
Hope this helps!
I have a friend who runs an online auction website. He currently has a featured items section on the homepage that he wants to have cycle an item every X amount of minute. The site runs off a MySQL database which I haven't actually seen yet.
The current code that he is using is a big, long messy Javascript code that is causing all kinds of errors.
The items would have to cycle in order and when they get to the end, go back and repeat again.
What would be the best approach to take to this using PHP?
EDIT: I mean from a backend SQL perspective. Not the UI.
Thanks
Ben
Assuming you have a separate table for the featured items (probably has an item ID referencing the main items table and maybe other info)... In this table, add a last_featured column to represent the time the item was last shown. From there, you can manipulate your queries to get a rotating list of featured items.
It might look something like this (as a weird pseudocode mix between PHP & MYSQL):
// select the most recent item in the list, considered the current item
$item = SELECT * FROM featured_items ORDER BY last_featured DESC LIMIT 1;
if ($item['last_featured'] > X_minutes_ago) {
// select the oldest item in the list, based on when it was last featured
$item = SELECT * FROM featured_items ORDER BY last_featured ASC LIMIT 1;
// update the selected item so it shows as the current item next request
UPDATE featured_items SET last_featured=NOW() WHERE item_id = $item['item_id'];
}
Note that this requires 3 call to the database... There may be a more efficient way to accomplish this.