I have a trivial question. Im using PHP+MySQL managing a huge DB
I want to search in a entire table a keyword I write in a input.
The problem is that the main table have +100 columns, so I had to write the php query manually
[...]
$sql="select *
from db
where ID LIKE '%".$q."%' or USER_ID LIKE '%".$q."%' or Phone_ID LIKE '%".$q."%' or
Fax_ID LIKE '%".$q."%' or email_ID LIKE '%".$q."%' or [...]
And this is a chaos when I modify a column, or add/remove...
Exist any other way to make this search? If not, I tought about create a separate PHP function, that obtains all column header names, and create an auto-fill function inside.
I tried to look for info with no success
https://stackoverflow.com/search?q=search+entire+table
Unfortunately there isnt any simple way to do this.
One option is to select all columns in table, fetch them as array and iterate over them and build your WHERE clause.
select column_name from information_schema.columns
where table_name = 'TableName'
This will make whole script slower, if you want to go this way i would recommend you to use some caching.
You could get the column info for the 'main table' using info from the information schema. Here are some methods for using MySQL. Here is how to do it using PHP.
You can do a SHOW COLUMNS on the table, then loop over the Field to get all the column names in the table, at least that way you don't have a hand-coded mess to deal with.
Related
I would like to write an sql statement for search. Here is sample database structure.
For eg, I want to display all records with topic '13'. How can i write sql query for searching 13 from the above structure? Any suggestions?
Can i able to use WHERE Topic LIKE '%13%'? Anything wrong with this?
Try this one:
SELECT * FROM `TABLE_NAME` WHERE `Topic` LIKE "%13%";
It's better and faster to save it in a third table of many-to-many relationship.
If you want to save as per your example (single table), try to save data as eg ",10,13,15,"
always have coma before and after, thus the following sql will exclude 213 and 132 etc
select * from table_name where Topic like '%,13,%'
select * from table where find_in_set("13",topic);
or if topic is not used as a set, you could do ...
select * from table where concat(",",topic) like "%,13,%";
The 2nd isn't real elegant but I've had to do that a couple times.
Because the data isn't really normalized, I used concat to add a comma to the topic field so I could make sure the "like" comparison would pass with a comma before and after the value. I suppose we would also have to remove any unwanted spaces as well for this example, so ultimately it would end up like:
select * from TABLE where concat(",",replace(topic," ","")) like "%,13,%";
Ultimately, we have to know what to expect in the topic column to come up with a query that would always work. In the past, I've had situations where I would add values to a string field (i.e. topic) with a delimiter before and after each value like:
(1)(2)(3)(14)(15)(255)(283)
If you did something like this for the topic field, the query is simple ...
select * from table where topic like "%(13)%";
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.'%'");
EDIT:Well I guess I should asked then before this question, would it be better to have a database full of tables(college names) that stores numbers than can be sorted in ascending order, or have a database with one table and select all the rows with the same "college name" and then sort the data from those rows after?
"
Is it possible to add a table in a database like...
CREATE TABLE table_name
(
column_name1 data_type,
column_name2 data_type,
column_name3 data_type,
....
)
...but call from a webpage instead of adding a table through mysql? So make a table in a database from code on my website?"
Yes you can send SQL queries through PHP.
Here is a resource that shows just what you're looking for I think
PHP MySQL Create Database and Tables
edit:
It depends on what you're doing, but I agree with the above comments that creating a table on page view is in most cases the wrong move.
If they all have the same basic structure I would put them all in the same table, and you can index the "college name" column. Reading from the database even with many many rows will still be quick, and if you decide to change something later you won't have to change X amount of tables.
You can also retrieve sorted results
SELECT * FROM Colleges WHERE name = 'University of Wisconsin' ORDER BY student_count ASC
I am trying to understand what is the best way to construct a query string with php when there are multiple columns I want it to look for.
For example the database has id, name, email, date.
And I have a search input field on a page which when submitted, I want it to search based on the input field against the above mentioned columns. Best what is the best way/practice to do that?
I have the following so far but it seems like it is a "dumb" search.
"SELECT * FROM Table WHERE id LIKE '$search%' || name LIKE '$search%' || email LIKE '$search%' || date LIKE '$search%'";
Well this sort of works but I feel there has to be a better way and a more appropriate smarter method.
Thanks...
You cannot make mysql use index properly when you are querying multiple columns and not using AND (you are using OR)
There is always need to optimize your query strategy, always people think the data is small,
why bother to spend effort to optimize ... but the truth is you don't know when your data will grow
For your query, if you want to stick to LIKE,
then you need to build 4 indexes on the 4 columns,
alter table Table add index on(id);
alter table Table add index on(name);
alter table Table add index on(email);
alter table Table add index on(date);
And change the query to :-
SELECT * FROM Table WHERE id LIKE '$search%'
union distinct
SELECT * FROM Table where name LIKE '$search%'
union distinct
SELECT * FROM Table where email LIKE '$search%'
union distinct
SELECT * FROM Table where date LIKE '$search%'
What is Union ?
Off-topic issue :-
you did not escape for user input, it could lead to SQL injection
is meaningless to search on ID when the input could be anything
same go for date
I found myself asking the same question a few years back. For the kind of functionality you are looking for, the most efficient way is full text search. Of course it come at the cost of space. I did not find any other way of implementing this efficiently. sorry i do not know if fts is supported in mysql.
This is a bit of a difficult problem for me to word, and I may be going about it in the completely wrong way.
I'm storing a set of options in a database, where each option is its own column. The user can change the number of options, however, so I need a way of allowing PHP to always select all the options.
Let's say I have these columns: options_dialog_1, options_dialog_2, options_dialog_3, options_dialog_4
There could be a varying number of these dialog option columns, eg, another called options_dialog_5 could be added.
How do I select all the dialog option columns, based on their column name format?
I think you have a database design problem here; repeating columns like that always leads to trouble in the end. I think you need two tables, one for the user and one for the options defined something like this...
USERS
id
name
OPTIONS
id
user_id
option_dialogue_number
option_dialogue_value
That turns the columns into rows, which are rather easier to get at.
Brian's answer will really, really pay you off in longer period. But if you need something quick & ugly, you can check out the "metadata dictionary" (tables that store information about all other tables, columns etc). You could get list of columns from it with first query and use it to build the second one.
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='mytable' AND COLUMN_NAME LIKE 'options_dialog%'
Visit the manual on INFORMATION_SCHEMA for more goodies.
I am not sure I understand the problem. Are you looking for
SELECT * FROM options_table
Something like (faux SQL - wont work)
SELECT ( SELECT column_names where column_name LIKE 'options_dialog%' )
FROM options_table
sounds not feasible to me (though I am sure it's possible somehow). If you need this, either consider refactoring the database design or maybe use a bitmask to store the selected options in a single column.