Select from mysql database where columns contains PHP - 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.

Related

How to separate SQL column data separated by comma to individual values and then count these values

Am using a SQL command in PHP to count the no of values inserted in a column named attack_type. I want to count the occurrence of individual values like website defacement in the whole column of the table. But here the column attack_type contain different values, separated by a comma and the count is treating whole column data as a string. Below is my current SQL statement with its output
I tried explode print_r in PHP
SELECT attack_type,
count(*) as number
FROM data_input_test
GROUP BY attack_type
Here is the output of the above statement
generated:
https://drive.google.com/open?id=1TyRL_Mh0OOJWaCpFczxmBr34No9LUpzH
But what I want is :
https://drive.google.com/open?id=1eeA_1TCER0WMpZwSkBDMzRtRa8xihbZd
and so on. The above desired output is edited to show what I exactly want.
Other answer on stackoverflow and on other forums are either irrelevant or are using regrex or a new table creation in one or the other way. That I don't want as my hosting has some limitations. My hosting doesnt provide creation of triggers, regrex or creation of temp tables
I may have a solution for this but don't know how to apply here. Possible here: https://www.periscopedata.com/blog/splitting-comma-separated-values-in-mysql
Please someone explain me how to apply the same here.
So I finally worked around to get my work done using the select only. This only works if you have a finite set of data or specifically less than 64 values.
Change your column datatype to 'set' type. And enter your set values.
Now use select, count, find_in_set and union functions of sql.
Example:
union select 'Un-patched Vulnerable Software Exploitaion'as type, count(*) as number from data_input_test where find_in_set('Un-patched Vulnerable Software Exploitaion',attack_type)```
and so on for all your values
I know this is not how you should do but as the legends say this works 😎😎
If you just want to count comma-separated values in rows, you can use:
SELECT SUM(LENGTH(attack_type) - LENGTH(replace(attack_type, ',', '')) +1) AS TotalCount
FROM table_name;

sql statement syntax for search

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)%";

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 :)

Selecting all columns that start with XXX using a wildcard?

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.

MySQL search for a number in VARCHAR field

I have a field in my database that contain comma separated values these values are numbers, and I am trying to do a search and count the number of times that a number appears in that column throughout the column,
$sql = "SELECT sector_id_csv, COUNT(sector_id_csv) as count FROM cv WHERE sector_id_csv LIKE '$sectorId'";
This seems slow and does not return any results, and I know the sector_id it is search exists in the table.
Basically, this should work fine if you use % wildcards:
WHERE sector_id_csv LIKE '%$sectorId%'";
what tends to cause problems in this scenario, though, is the fact that a search for 50 will also find 501 502 503 and so on.
If you can rely on your comma separated list to have a trailing comma behind every entry, it would be more reliable to search for
50,
to catch that value only.
WHERE CONCAT(',', sector_id_csv, ',') LIKE '%,$sectorId,%'
or
WHERE FIND_IN_SET('$sectorId', sector_id_csv);
This will ensure that your query returns only rows with sector id in given field. Provided that sector id-s in this field are comma separated.
Any query using LIKE or FIND_IN_SET will be slow as it cannot take advantage of indexes. Please consider putting all sector id-s in separate table.
Also for security reasons please remember to ensure that $sectorId is a number by casting it to int like that:
$sectorId = (int)$sectorId;
before using it in a query.
Don't you need to pad the value with the % wildcard for LIKE to work?
$sql = "SELECT sector_id_csv, COUNT(sector_id_csv) as count FROM cv WHERE sector_id_csv LIKE '%".$sectorId."%'";
At least that's my understanding from reading this article, your use of wildcards will depend on your desired condition.
...but if your scema was normalized you wouldn't need to jump through these hoops - and it would run a lot faster.
C.
Actually the number could be at he beginning or the end too. So you need to do
WHERE sector_id_csv='$sectorId' OR sector_id_csv LIKE '%,$sectorId' OR sector_id_csv LIKE '$sectorId,%' OR sector_id_csv LIKE '%,$sectorId,%'
SELECT count(*) from TABLENAME where FIND_IN_SET('VALUE',FILDNAME)>0;
Others u can use instr, regexp....
It's advisable to have FILDNAME indexed.

Categories