Linking two tables in a query - php

I have two fields... one is category name and other is document title... When i click on submit... the document title should be saved in document table linking to the category name selected... which is in other table.
A category can have n number of document titles...
$result = mysql_query("UPDATE stinky_menu SET description = '$docuTitle', url = '$linkTitle' WHERE title = '$catID'");
How can i perform another query to my other table to in WHERE clause.

Generally I handle this kind of case by having the select box in the HTML form return the Category ID, not the title. That allows me to insert or update the record without the need for an additional lookup to my reference tables (in this case your category table).

Using :named form for the parameters (?-form also works of course), simplest way to do what you want is to use a FROM and JOIN in your UPDATE -- something like (depending on some details you haven't provided):
UPDATE stinkymenu
SET description = :docuTitle, url = :linkTitle
FROM stinkymenu
JOIN categorytable
ON stinkymenu.catId = categorytable.id
WHERE categorytable.title = :catId
See PDO's docs for the way to use such a "prepared statement" and bind its parameters to your variables.

Related

Is there any way to search from the result in query?

I am making pagination in core PHP (actually first time). As user will press the pagination button for example user pressed second pagination button. then this query generates:
SELECT * FROM product LIMIT 12, 12
It is executing perfectly as I expected. but the main problem is that if user wants to do filtration on that specific page for suppose user wants all items which are present in page 2 and category_id must be 3 then this query generates:
SELECT * FROM products WHERE category_id IN (3) LIMIT 12, 12
But I am getting the empty resultset... What I am doing wrong?
The pages are based on the number of lines your query returns. You cannot apply a filter on a single page on the DB side as any additional Wheres would change the elements in the pages of the previous query.
In your case, adding WHERE category_id IN (3) results in no lines, making your new page empty.
You could implement filters in your frontend, or backend AFTER the query returns the result, and your filter would remove items from the DB result.
Ideally, every time your users interact with the UI, it would result in a new call to the DB with the filters being applied on the query. then show the result to your user.
If I understood correctly you want to change the WHERE clause in any way between pages and you not want any previous records be repeated.
If you have a unique id in your table and that id increases with each page you can use for a bookmark. I have a simple procedure to make that column. Then you can create a column specifically for this app.
You create a bookmark column and add it to the WHERE clause.
This column will give you a bookmark to save the user's position.
You save this column's value from the last record.
Then in your query you can add this position your query in the WHERE clause
WHERE `bookmark` > $position AND ...
Then you can make any change between any pages at any time you want to the WHERE clause and you will never repeat a previous record.
Making this new column is very simple and does not require much storage.
Use the same ORDER BY from your page query and make your WHERE 1.
$sql = SELECT `product_id` FROM `products` WHERE 1 ORDER BY `category`, `description`";
$results = mysqli_query($conn,$sql);
while(list($product_id) = mysqli_fetch_array($results, MYSQLI_NUM)){
$bookmark[] = $product_id;
}
foreach($bookmark as $position => $product_id){
$sql = "UPDATE `products` SET `bookmark` = $position WHERE `product_id`=$product_id";
}

Showing category content with sub categories content

I have main categories and sub categories.
at cat.php?id=1 page; (id=1 is main category)
I want to show also subcategories content.
My categories table:
id - sub - title
(if sub=0 it means this is main category. if not it's sub category)
My current query is like that;
<?php
$id = $_GET['id'];
$data = mysql_query("select * from content where category=".$id." order by id desc");
while($r=mysql_fetch_array($data))
{
echo "$r[id] - $r[title]";
}
?>
Shows only main category content, but not sub categories content. (at cat.php?id=1)
*
I think I must connect the categories table again to get sub categories' ID. ???
Surely, I need a new query. I need to get sub=".$id." and list here in the same page.
I stuck.
So you need to get the Id's of the subcategories as well, you can embed a second query inside of that query (or split it into two separate ones, but that adds another request to the server).
You would put something along these lines:
$data = mysql_query("select * from content where category IN (SELECT id FROM categories WHERE id='$id' OR sub='$id') order by id desc");
using the WHERE ... IN lets you select multiple values from a list like (3,5,2)
So it will look similar to this when the subquery executes:
select * from content where category IN (1,3,2,5,13) order by id desc
WARNING:
You need to sanitize your $_GET['id'] so that no sql injection occurs, this will currently allow sql injection.
Also, the mysql_ functions are deprecated and you need to start using PDO prepared statements, I am not familiar enough with them, but they will do the sanitizing of user input for you.

Performing Searches with Dynamic Filters and Dynamic Joins in Yii

I'm having issues performing a query and have not found anything that suited my situation, so here is my scenario.
I'm displaying a dataTable with information and have multiple filters that I can apply.
So far, so good.
The issue now is that I have to implement something like dynamic filters, meaning:
The user presses a button that says "Add Filter"(he can press it as
many times as he wants to add multiple filters).
When he presses that button, a div element appears with 2 elements inside.
A dropdown list and an input box.
The user can select the field he wants to search on the dropdown list
and writes the value he wants to be searched in the input.
He presses "Search" and the query is performed.
Lets say that in the dropwdown list the user chooses the option "Company" and in the search field he writes "foo bar".
In the controller, I detect that the option "Company" was selected. The thing is, "Company" is not in the main table I'm searching, it is for example, 2 relationships away. As it is also possible to export data from that table, I'm doing LEFT JOINS, but am having dificulty binding the params.
I've tried multiple things, I am currently:
//this initial query is always performed
$test_query = 'SELETC a.*
FROM tableA a
LEFT JOIN TableB b ON b.name = a.name
';
$whereTxt = "<some_other_where_conditions>";
$bindParam[':some_field'] = $_POST["field_value"] //this $_POST is here only for better understanding, I don't actualy have the untreated value here.
Now, if "company" filter was detected in the dropdownlist:
if($company_filter){
$test_query .= 'LEFT JOIN relation_table1 t1 ON a.team_id = t1.id
LEFT JOIN relation_table2 t2 ON t1.company_id = t2.id';
$whereTxt .= " AND retaion_table2.company_name LIKE :company_name";
$bindParam[':company_name'] = "% ".$_POST["company_name"]." %";
}
The issue is here
How do I wrap this all up?
I tried:
$list = $this->getDBConnection()->createCommand($test_query)->where($whereTxt, $bindParam)->queryAll();
Fails, the where parameter isn't even considered in the query execution
If tried other variations but the outcome is the same, the params are unbinded or the query fails.
Ideally, I would have:
$list = $this->getDBConnection()->createCommand()
->select("a.*")
->from('tableA a')
->leftjoin('regular_join')
->leftJoin('other_regular_join')
->where($whereTxt, $bindParam)
->queryAll();
But this way, I cannot add
->leftJoin(...)
dynamically corect? Which I really have to because of the filters the user might/might not have selected.
tl;dr
using getDBConnection()->createCommand() I need to insert LeftJoins dynamically depending on what the user chooses in the search filters, binding where parameters and arguments
I am aware that what I'm trying to achieve may not be clear, so apologies if I couldn't make myself understand.
Don't know why I was so confused.
Instead of binding the where params I just appened the where to the query itself and then binded the values after, ending up with something like:
$test_query= 'SELECT a.* FROM ....';
if($company_filter){
$test_query .= 'LEFT JOIN relation_table1 t1 ON a.team_id = t1.id
LEFT JOIN relation_table2 t2 ON t1.company_id = t2.id';
$whereTxt .= " AND relation_table2.company_name LIKE :company_name";
$bindParam[':company_name'] = "%".$_POST["company_name"]."%";
}
$list = $this->getDBConnection()->createCommand($test_query." WHERE ".$whereTxt)->bindValues($bindParam)->queryAll();
Also, kudos to dgtal#Yii forum

saving comments for different content type

i have different content types on my website.
f.e. - articles, questions, posts
i see two ways for storing comments.
1) for each content type create table like articles_comments, post_comments etc.
2) create one table with fields parent_field and parent_id. in 'parent_field' save smth like articles_id or posts_id. so with
explode('_', $parent_field);
I can recieve parent table name and field name for
select "... FROM $table WHERE $field = $parent_id"
second way seems mor flexible, but first easier.
so, the question is: which way is better, in case of 100+k hosts everyday?
one table solely for comments
id, caption, body, ...
one relation table to store the parent relationship to the comment
comment_id (int),
parent_id (int),
parent_type (enum, set, or int BUT not varchar)
// build index
which this, you can easily tagged comment to multiple parents (if you want to),
and also can easily do INNER JOIN to get comments belong to a parent
another benefit,
such as if you want to get most comments for all article,question and post,
in your method,
you would require three INNER JOIN + GROUP BY,
with my suggestion, you only need single query
most importantly,
the relation table is able to handle huge amount of records
because it only store integer (smaller index)

Selecting rows from MySQL

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!

Categories