how to query results based on data in a db row - php

All right. I asked a question looking for suggestions on here once, and I was told that wasn't allowed. I was told to state a specific problem, and ask for a specific answer. So as per moderator instruction here I go.
I have two tables in my db. One table is nothing but several rows filled with different category options. Then on my other table there is a row called cat where one of the category terms found in the first row is stored.
I want to query out all of my category options from th table of nothing but categories as hyperlinks. Then based on the link chose run a query that looks something like this
SELECT cat FROM categories WHERE categiories=chosen cat term
I have general knowledge in php so I could figure out how to do what I want with a point in the right direction. My specific problem is that I do not know what to look for. Can someone please tell me what to look for? I have no problem with the query. My main problem is where would I point the hyperlink so it generates the page with the select statement upon request. What can I look for that will help me figure out how to do this? i am very good at dissecting and figuring things out.

Point it to another PHP file via hyperlink like this
another.php?term=foo
on the another page connect to PDO and have a code like this
$stm = $pdo->prepare("SELECT cat FROM categories WHERE categiories = ?");
$stm->execute(array($_GET['term']));
$cats = $stm->fetchAll();
now you can iterate over $cats array

Put somewhere in your HTML the link like this.
Link
You can think of the PHP-file getting a param like that. Just read the param that way:
$term = $_GET["term"];

Related

Search tags in mysql table with PHP

I have a table with some submissions, this table has a tags field, and I need to search in it.
The data is saved in JSON format in the table, like this: ["basic","example","html","chart"]
I'm trying to find a way to search all rows in the tags fields, but not sure how it can be done the best way when it is in this format.
The user submits an tag to search, like: html, then I need to search all rows for that tag, without to much overhead.
I know most people use to say: what have you tried yourself?
- well, nothing. As I have no clue how to do this, I know how to search in sql and all that. but never tried it in this logic.
There is no "best way" to search in this format. There is no way at all.
No wonder you have no clue how to do that. I'll tell you more - no one knows it either. Tags should never be stored in json format. It is like as if you built a car, placing wheels on the roof. And then come asking, how to drive it.
You have to learn database basics first. And then create your tables proper way. making a separate table for tags. Storing each on a separate row. After that you will be able to search a tag usual way, using JOIN query to attach the corresponding records to the result.
$sql = "SELECT a.* FROM articles a, tags t WHERE aid=a.id AND tag=?";
$stmt = $pdo->prepare($sql);
$stmt->execute(array($tag));
$data = $stmt->fetchAll();
You should create another table tag with fields name, post_id.
I believe that is the best solution to do a search feature.
If you do not have permission to create database table. It depends on how many posts you have. a few? hundreds or even more? If there is not a huge rows of your post table. You can fetch all of them and decode to PHP Array and then use string comparison.
Or maybe, you can give up the database way, just handling with a cache file. We're only need to write cache if user create/modify a post.
But you also can use the unreliable way, using like operator in mysql.
You should take a look at the MySQL fulltext index.
Take a look in the manual and this Zend Developer article
But you shouldn't use fulltext searching for many columns.
In one of my projects I worked around it by concatenating to be searched columns in a TEXT column and apply to the fulltext index on it.
It's simple you can try using like query
SELECT * FROM `post` WHERE `tags` LIKE '%html%';
In PHP Variable:
$tag = "html";
$query = mysql_query("SELECT * FROM `post` WHERE `tags` LIKE '%'.$tag.'%'");

PHP/MySQL join with CSV array

I have a tricky (well for me it is) question about getting info from 2 different tables.
I have an array, like this:
$abc=$_COOKIE['cookie'];
$comma_separated = implode(",", $abc);
Now, the array will be a CSV list of ID's that need to match ID's from the "Specials" table. In the "Specials" table there is a column called Contract Name. This Contract Name column needs to match a column of the same name, each unique, in the Products table, and display the information contained therein.
My currenty MySQL query looks like this:
$query= "SELECT specials.id,
specials.product_name,
specials.contract_name,
specials.included_value AS inc_val,
specials.image_url,
specials.contract_monthly,
specials.outlet,
products.package,
products.bundled,
products.included_value
FROM specials,
product
WHERE `id` IN ('.$comma_separated.')
AND specials.contract_name = `products.package`";
What happens is... that nothing happens. I've tried wrapping my brain around some of the JOIN tutorials but no luck.
So basically I'd like to display a list of current specials, along with the package info, which is contained in a different table. I've tried wrapping my brain around some of the JOIN tutorials but no luck.
To my knowledge I'm crap at explaining things properly, so please do shout if I can shed any more light on this conundrum.
Thanks! :)
To even start to get this to work, your $query string is going to have to be a valid query. Ordinarily, to troubleshoot this kind of problem, you do echo $query; somewhere along the way to see if it is valid. You then might even paste the query's textinto a standalone MySQL client (phpMyAdmin, or maybe HeidiSQL or something) to see what you get.
Looking at this line:
WHERE `id` IN ('.$comma_separated.') /* wrong! */
it looks like it needs to read
WHERE `id` IN (".$comma_separated.")
because you're using double quotes to surround your fragments of SQL text. Also, you might want to use
WHERE `specials`.`id` IN (".$comma_separated.")
just because some other tables might contain id columns and then your search clause will be ambiguous.

MySQL table/query design - multiples of one item, many comments

I have a site which display images, up to 30 per page.
Users can comment on the images and these comments, or at least the first few, appear under the image if there are comments.
I have a table of image references linked to a folder on my server.
e.g.
image_id // image id
user_id // user who added
image_url // ref to image
Then a separate table for all comments
comment_id
image_id // link to images table
comm_poster_id // id of user who posted comment
Now, the question is what the best way to call the information together? Ideally in one select
I can't really ajax call under each image as that would be 30 db calls per page which would kill it so whats the alternative/best method?
To clarify, in the select there would only ever be 1 image but there could of course be multiple comments for an image
Hope i've given enough info
EDIT To clarify, the question is what is the best way to collate all this information together for display - can I run one query which pulls all the images in on the page also somehow pulls the comments for images in if they exist.
As for how I would like the data to look... I don't know. This is the first time I've done anything like this so guidance needed if possible.
Ok, well I'm not a php expert, but I got you started on the sql side of things. I CAN help you with php, but there are others here that are more versed in it that I am.
I started this sqlFiddle for you, go have a look and you can tinker with the query to get what you want.
http://sqlfiddle.com/#!2/79ecf/1/0
From the php side, until you know how you want to display your data, it's difficult to say what your query needs to look like. I went with this for the time being:
select *
from images i
inner join comments c on i.image_id=c.image_id;
This is a VERY simple query and you will probably end up needing to add to it.
I'll assume you are using mysql as most people using php choose mysql. From my understanding there are 2 ways to connect, mysqli and pdo. PDO seems to be emerging as the preferred method, but I know nothing about it. Here are references for both. Just DO NOT USE mysql_query(), it is deprecated so don't bother learning any part of it.
PDO: http://dev.mysql.com/doc/refman/5.6/en/apis-php-pdo-mysql.html
MYSQLI: http://php.net/manual/en/mysqli.query.php
Either of these should give enough of a tutorial to show you how to query your database and then loop through the results to get to your data. It is then up to you how you want to display it on your page.
Hopefully this is enough to point you in the right direction.
Good Luck!
Your easiest approach is to just join the two tables together, sorting first by image and sub-sorting by comment.
SELECT i.*, c.comment_id, c.comm_poster_id
FROM images i LEFT JOIN comments c ON i.image_id=c.image_id
WHERE {whatever where clause selects your set of 30 images}
ORDER BY i.image_id, c.comm_poster_id
Use a LEFT JOIN or images without comments won't display.

PHP MySQL while loop not returning anything

I'm quite new to php and mysql so hopefully someone with more experience will be able to give me some guidance here.
I have the following code:
<?php
$npcname = $_GET['npcname'];
$npcinfo="SELECT * from npcs where name='$npcname'";
$npcinfo2=mysql_query($npcinfo) or die("could not get npc!");
$npcinfo3=mysql_fetch_array($npcinfo2);
$listquests = "SELECT * from quests where npcid = '$npcinfo3[npcid]'";
$listquests2 = mysql_query($listquests) or die("No Quests to list");
$listquests3=mysql_fetch_array($listquests2);
echo "<b>Quests Available for ".$npcname."</b><br>";
while($row=mysql_fetch_array($listquests2)) {
echo $row['name'];
}
?>
To go with this I have some tables whcih look like this:
npcs
name|location|npcid
quests
name|qid|npcid
So a quest is associated to a NPC via the npcid field.
I have one entry in each table.
Bob|Scrapyard|1
AND
Sort Scrap Metal|1|1
As you can see the quest and Bob both share the npcid of 1.
In my loop I am trying to list all of the quests for Bob. However on running the code I do not get any quests listed.
If I put the code:
$listquests3['name'];
Outside of my loop it successfully displays "Sort Scrap Metal" as expected. The reason I have used the loop is to display multiple quests when I add them.
If somebody could be kind enough to take a look at the code and tell me what I have done wrong I would be grateful.
Thank You.
It may be a good idea to print out the SQL and run this against your database to see what results you get.
Looking at this it looks like there may only be one result which is fetched in the
$listquests3=mysql_fetch_array($listquests2);
line. Since there are no more results there is nothing to loop over.
The results are already fetched, since there is only one rule and you fetched it in $listquests3 :). It will work if you remove that line I think.
You need to do a INNER JOIN or a LEFT JOIN. Yes after carefully seeing the question again, I found that when doing the "mysql_fetch_array()" code for the first time (just before the "while" loop), the value of the variable "$listquests2" gets lost. So the "while" loop does nothing fruitful.
You must remove this single line for variable "$listquests3".
You only have one row, and you fetched that row when you called mysql_fetch_array the first time. When you call it the second time, there are no more rows to fetch in the result set, the function returns false and your loop exits.
This statement: "$listquests3=mysql_fetch_array($listquests2);" already fetches the first. Sicne you have only one, there's nothing more to fetch, so the next call to mysql_fetch_array will return nothing.
That should fix it, but for your own 'experience', this might be a good moment to start learning about MySQL joins (LEFT JOIN in particular). You can easily find a lot about it on the internet!

PHP join help with two tables

I am just learning php as I go along, and I'm completely lost here. I've never really used join before, and I think I need to here, but I don't know. I'm not expecting anyone to do it for me but if you could just point me in the right direction it would be amazing, I've tried reading up on joins but there are like 20 different methods and I'm just lost.
Basically, I hand coded a forum, and it works fine but is not efficient.
I have board_posts (for posts) and board_forums (for forums, the categories as well as the sections).
The part I'm redoing is how I get the information for the last post for the index page. The way I set it up is that to avoid using joins, I have it store the info for latest post in the table for board_forums, so say there is a section called "Off Topic" there I would have a field for "forum_lastpost_username/userid/posttitle/posttime" which I woudl update when a user posts etc. But this is bad, I'm trying to grab it all dynamically and get rid of those fields.
Right now my query is just like:
`SELECT * FROM board_forums WHERE forum_parent='$forum_id''
And then I have the stuff where I grab the info for that forum (name, description, etc) and all the data for the last post is there:
$last_thread_title = $forumrow["forum_lastpost_title"];
$last_thread_time = $forumrow["forum_lastpost_time"];
$lastpost_username = $forumrow["forum_lastpost_username"];
$lastpost_threadid = $forumrow["forum_lastpost_threadid"];
But I need to get rid of that, and get it from board_posts. The way it's set up in board_posts is that if it's a thread, post_parentpost is NULL, if it's a reply, then that field has the id of the thread (first post of the topic). So, I need to grab the latest post_date, see which user posted that, THEN see if parentpost is NULL (if it's null then the last post is a new thread, so I can get all the info of the title and user there, but if it's not, then I need to get the info (title, id) of the first post in that thread (which can be found by seeing what post_parentpost is, looking up that ID and getting the title from it.
Does that make any sense? If so please help me out :(
Any help is greatly appreciated!!!!
Updating board___forums whenever a post or a reply is inserted is - regarding performance - not the worst idea. For displaying the index page you only have to select data from one table board_forums - this is definitely much faster than selecting a second table to get the "last posts' information", even when using a clever join.
You are better off just updating the stats on each action, New Post, Delete Post etc.
The other instances would not likely require any stats update (deletion of a thread would trigger a forum update, to show one less topic in the topic count).
Think about all the actions the user would do, in most cases, you dont need to update any stats, therefore, getting the counts on the fly is very inefficient and you are right to think so.
It looks like you've already done the right thing.
If you were to join, you'd do it like this:
SELECT * FROM board_forums
JOIN board_posts ON board_posts.forum_id = board_forums.id
WHERE forum_parent = '$forum_id'
The problem with that, is that it gets you every post, which is not useful (and very slow). What you would want to do is something like this
SELECT * FROM board_forums
JOIN board_posts ON board_posts.forum_id = board_forums.id ORDER BY board_posts.id desc LIMIT 1
WHERE forum_parent = '$forum_id'
except SQL doesn't work like that. You can't order or limit on a join (or do many other useful things like that), so you have to fetch every row and then scan them in code (which sucks).
In short, don't worry. Use joins for the actual case where you do want to load all forums and all posts in one hit.
The simple solution will result in numerous queries, some optional, as you're already discovered.
The classic approach to this is to cache the results, and only retrieve it once in a while. The cache doesn't have to live long; even two or three seconds on a busy site will make a significant difference.
De-normalizing the data into a table you're already reading anyway will help. This approach saves you figuring out optional queries and can be a bit of a cheap win because it's just one more update when an insert is already happening. But it shifts some data integrity to the application.
As an aside, you might be running into the recursive-query problem with your threads. Relational databases do not store heirarchical data all that well if you use a "simple" algorithim. A better way is something sometimes called 'set trees'. It's a bit hard to Google, unfortunately, so here are some links.

Categories