Selecting all columns that start with XXX using a wildcard? - php

I have several columns in my databases with similar names.
How do I select those based on the word they start with?
Here's an example table layout:
I tried selecting all info for a particular thing (food kind in this example) using
$Food = "Vegetable";
mysql_query("SELECT `" . $Food . " %` FROM `Foods`");
but it didn't seem to work.
Any help would be appreciated :-)
EDIT: Apparently this wasn't clear from my example, but I already know all column's first words. The columns are always the same and no 'food kinds' are ever added or deleted. The PHP variable is only there to determine which one of a couple of set kinds I need.

You'd have to build the SQL dynamically. As a starting point, this would get you the column names you're seeking.
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'Foods'
AND table_schema = 'YourDB'
AND column_name LIKE 'Vegetable%'

There's no way to do exactly what you're trying to. You could do another query first to fetch all the column names, then process them in PHP and build the second query, but that's probably more complex than just writing out the names that you want.
Or is there a reason this query needs to be dynamic? Will the table's structure change often?

Here's a way I did it purely with MySQL:
SET SESSION group_concat_max_len = 2048;
SELECT GROUP_CONCAT(CONCAT(" ",CAST(column_name as CHAR(50)))) FROM information_schema.columns WHERE table_name='real_big_table' AND column_name LIKE 'prefix%' INTO #sub;
SET #x = CONCAT("SELECT ",#sub," FROM my_db.real_big_table WHERE my_db.real_big_table.country_id='US'");
PREPARE stmt FROM #x;
EXECUTE stmt;
My answer is inspired by this answer.
Note: My 'inner-DBA' (in the form of a small angel on my shoulder) tells me that needing to do this is probably a sign of bad DB structure, but my 'inner-hacker' (in the form of a small devil on my other shoulder) says "just get it done!"

Convert your database to one with three columns:
Product_type (vegetable, fruit, etc)
Name (apple, carrot, etc)
color (orange, yellow, etc)
Now you can use your wildcard to obtain only a certain type, because it now is IN a columns, not in the header.

How about creating the query in 2 steps?
1- Get the column's name from the db schema (or elsewhere)
2- Generate an sql query with the column's name that match your filter condition.

Related

Sql select including columntype

I want, for my form in php, a result including columntype.
Is there a way to make a query and including the column type?
select * from TableA
+
SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'yourTableName'
There's probably no way to select both data and column type because the column type is typically stored in a separate table (this would depend on the database). For example, in MySql:
Query to column type:
SELECT COLUMN_NAME,DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = 'TableA'
You would then to need to parse the results of the 2 queries and join them using php (I don't think there's an easy way to do this using SQL because you would be joining a 1xN results with a Nx1 result).
More info about where the column type is stored:
http://dev.mysql.com/doc/refman/5.7/en/information-schema.html
Those are inherently different data sets so I bet you'd need to write a possibly rather messy stored routine.
You don't explain why you need it but I suspect you'll be fine with the column types of the result set (rather than the source tables). That will include exactly the same information plus the type of calculated columns.
The exact mechanism depends on your DBMS and database library. You don't give any clue about that but your sample code looks like MySQL so the options include:
PDOStatement::getColumnMeta()
mysqli_stmt::result_metadata()
If you want to stick to your original spec, at least save yourself some trouble and just run two queries.
I found this. So now i can combine the array!
$i = 0;
while ($column = $query->getColumnMeta($i++)) {
print_r($column);
}

Check if mysql field contains a certain number in mysql query

I am having a table with a column that has few ids that were put into database with multi select. Column for example contains: 1,4,5,7,9. Is it possible to check if this column contains for example number 5 or not in it through MySQL query ?.
I need to select all the people that have number 5 or some other listed in that field and print them through php.
http://dev.mysql.com/doc/refman/5.6/en/string-functions.html#function_find-in-set
SELECT ...
WHERE FIND_IN_SET(5, list_column)
But understand that this search is bound to be very slow. It cannot use an index, and it will cause a full table-scan (reading every row in the table). As the table grows, the query will become unusably slow.
Please read my answer to Is storing a delimited list in a database column really that bad?
You can use #MikeChristensen's answer to be more standard. Another trick with standard SQL is this:
select * from TableName
where ',' || ids || ',' LIKE '%,5,%'
(in standard SQL, || is the string concatenation operator, but in MySQL, you have to SET SQL_MODE=PIPES_AS_CONCAT or SET SQL_MODE=ANSI to get that behavior.)
Another MySQL-specific solution is to use a special word-boundary regular expression, which will match either the comma punctuation or beginning/end of string:
select * from TableName
where ids RLIKE '[[:<:]]5[[:>:]]'
None of these solutions scale well; they all cause table-scans. Sorry I understand you cannot change the database design, but if your project next requires to make the query faster, you can tell them it's not possible without redesigning the table.
Perhaps:
select * from TableName
where ids = '5' -- only 5
or ids like '5,%' -- begins with 5
or ids like '%,5' -- ends with 5
or ids like '%,5,%' -- 5 in the middle somewhere
It probably won't be very fast on large amounts of data. I'd suggest normalizing these multi-selection values into a new table, where each selection is a single row with a link to TableName.
select * from your_table where concat(',',target_column,',') like '%,5,%'
you can write the sql query like this, for example you are looking for the number 5
select * from your_table_name where ids='5'
if you want to check the result with php just tell me i will write it for you :)

Select from mysql database where columns contains PHP

I have a database and some of the columns contain things like CA, GB etc, although some contain multiple country codes like
US+GB+CA+AU
I'm just wondering what kind of query I would do that would return that row when I'm searching for just CA or just GB, and no necessarily the whole package US+GB+CA+AU
Encase that's a little confusing, basically I just need to return that row based on a search for just CA or just GB etc.
Thanks
Use FIND_IN_SET(), but you'll first need to replace + with , since it expects a comma-separated string. Even without the
REPLACE(), this is will not make use of any index on the countrycodes column.
SELECT * FROM tbl
WHERE FIND_IN_SET('AU', REPLACE(countrycodes, '+', ',')) > 0
The proper long term solution, however, is to change your database structure to normalize these country codes into a table that contains only two columns - a country code, and the id of the associated row from the table you're attempting to query now. You can then index the column appropriately to improve performance (possibly drastically improve it).
I would recommend to normalise it like liquorvicar said.
but using SELECT ... WHERE countrycode LIKE '%GB%' would work.
http://w3schools.com/sql/sql_like.asp
It's not a good solution, but you can use LIKE for your query:
SELECT * FROM `table` WHERE `field` LIKE '%+CA+%' OR `field` LIKE 'CA+%' OR `field` LIKE '%+CA' OR `field` = 'CA'
Last two checks for firs and last values.

Search for column format

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.

PHP/MySQL - How do you determin the field names from a given query result?

Given a result set, how can I determin the actual names of the fields specified in the query (NOT their aliases).
$query = "SELECT first AS First_Name, last AS Last_Name FROM people";
$dbResult = mysql_query($query);
$fieldCount = mysql_num_fields($dbResult);
for ($i=0; $i<$fieldCount; $i++) {
// Set some values
$fieldName = mysql_field_name($dbResult, $i);
}
This example returns field names, but in this example it returns the alias "First_Name" instead of the actual field name "first".
Is it possible to get the actual field name from such a query. Particularly if I am writing a function and have no idea what query will be thrown at it.
If you are using MySQLi:
http://www.php.net/manual/en/mysqli-result.fetch-field.php
The field object has a "orgname" property.
The "classic" MySQL equivalent function doesn't report back the original column names.
Short answer: you don't.
Long answer: Once the dataset is pulled by MySQL and sent back to PHP, the only information PHP now has is the columns, or aliases if you used them. There is no way to look at a result set and determine what the original column names were. You have to switch to another DB driver like mysqli to obtain this info.
Your question doesn't make sense.
What are you going to do if you get a derived column i.e.
select column_a + column_b as order_total from orders;
are you saying you want to know that the original query was column_a + column b ??
if so, you probably need to write a query parser, or get one off the internet.
I think the implementation of that is beyond the scope of your question though :)
I'm not 100% sure about this, but I would say: there is no way.
The MySQL gives you back the result set, nothing more. It does not return the select statement nor any details about it.
So you cannot get the original field names because the server will provide you the information you asked: alias names.
If you don't mind making a second query (and your using MySQL 5 or greater) you can ask information_schema for the names.
Check out MySQL Reference for the details:
SHOW COLUMNS FROM tbl_name;
if you have access to the string of the query you could try a regular expression to parse it.
I'm no regex master but you could chop up the string by looking at the text between 'select' and 'from' then grabbing all the field names as either
field FieldAlias
or
field as FieldAlias
If you're trying to write some functionality to let you know what fields are being fetched for handling updates - the only way to do this correctly is for it to present an SQL-less interface to the code above and manage all SQL generation itself. This is called a data abstraction layer.

Categories