Find Max numeric value of two varchar fields - php

I'm trying to find the max value contained in two separate fields of my table.
The code I'm using in my model is:
$query = $this->db->query("select max($field1) as max_id_1 from default_table1");
$row1 = $query->row_array();
$query = $this->db->query("select max($field2) as max_id_2 from default_table1");
$row2 = $query->row_array();
return max($row1['max_id_1'], $row2['max_id_2']);
I'm a complete novice where PHP and CodeIgniter is concerned - as I'm sure my code demonstrates :)
It is working insofar as it's returning values, but not the maximum values I have in the fields. For instance I know there is a 4000 value but the highest returned is 750.
I'm wondering if this is because the fields are of type VARCHAR because although they predominantly contain numbers there are some that contain characters (- or &) or the word 'to' so I couldn't use the INT type.
Because of using VARCHAR is it failing to see that 4000 is larger than 750?
If so is there a way to cast the field contents as integer before checking for the max value, and will this be affected by the non-integer values in the fields?
All offers of help and advice is gratefully received.
Tony.

This can be done using SQL using MySQL's implicit type conversion:
select max(case when (field1+0)>(field2+0) then field1+0 else field2+0 end)
from default_table1
Using +0 would convert varchar to number and also ignore any characters that follow after the number. If you still need the original content, you can write the query like this:
select case when (field1+0)>(field2+0) then field1 else field2 end
from default_table1
order by case when (field1+0)>(field2+0) then field1+0 else field2+0 end desc
limit 1

Oh, oops, I've forgot the mysql part
You should do the same thing, cast to integer:
select max(cast($field1 to unsigned)) as max_id_1 from default_table1
It depends of your data, but you may try something like that
return max((int)$row1['max_id_1'], (int)$row2['max_id_2']);
Have a look to the PHP doc on string to int conversion

What you are really asking for is a way for codeigniter to convert the strings to numbers, and the find the max values of those. I don't know of any way to do this in codeigniter.
If you really want this, you have two options:
loop through all the rows in the table, and use php to parse out the number, while looking for the maximum number
Add a number column to the db, and do the string-to-number parsing in this new column whenever the values are inserted.
The first option is incredibly inefficient, and the second is probably your best bet.

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;

How to save numbers to mysql database as it is?

I need to save numbers to database as it is please see the example.
currently i save number as 22.5 and in database it is saved as 22.
number in database is set as integer
//sometimes $number can be "33.5" or "33" or "1" or "1.003"or "03"
$sql = "INSERT INTO active (name, number) VALUES ('somename','$number')";
If you make your number column as DECIMAL data type, it will hold the decimal point with all numbers. Integer columns cannot hold decimal points.
If it is not your requirement, better use VARCHAR as data type (But NOT RECOMENDED).
Hope this helps.
First of all, you need to check the structure of active table. From your question, I understand that various types of number values is going to be saved to number column. And I guess the type of number column in active table is numeric for int types. For example, INT or BIGINT or any other integer types.
Here is what I'm usually doing. Just use varchar for number field. It might not sound like professional. But it's very easy to use. By doing so, you won't have any problem with saving numeric value to the column. I have got an similar issue before while saving latitude and longitude value to the table. And php has got many functions to get actual float or int value from string. So this is an easy and simple way to fix.
One of the easiest and reliable way to save the numbers/integers/floats to the database is to convert them to string and then storing them into the database.
Note : Your database column type should be of type string/text.
One of the advantage of this method is that you can overcome the limits of int/float/double.
$string_number = (string)$number;
$float_number = (float)$string_number;
If you want to save number as 22.5 and in database. Then you need to change table column structure. Instead of Integer/Int set to float Then Next set length 10,2
for information please check below screen short
Then you get proper output Happy Programming

Add value "001" to mysql database

I am trying to add the value "006" to an MySql row, but it shows up as "6"! any fixes on my code ?
$id = "006";
mysql_query("INSERT INTO Table (id) VALUES ($id) ");
Thanks,
If id is a numeric column such as an integer, 006 is the same as 6 so there isn't a way to explicitly save 006 since its exactly the same as 6.
But if you want to retrieve that integer as a 3-digit, zero-padded string, you could use the LPAD function to pad it with 0's on the left side:
SELECT LPAD(id, 3, '0') as id FROM table;
Although this is not a safe way:
$id = "006";
mysql_query("INSERT INTO Table (id) VALUES ('$id') ");
I think you forgot some quotes on values, so its cast to int.
Your field needs to be a VARCHAR for that to work as you desire. You may also pad leading zeroes when you run your queries as an alternative.
I suppose that's just incorrect value (for the int field type) and cannot be stored at all.
Database intended to store data, means data without any additional formatting, which can be added at select time. That's how this thing works in general.
So, I'd suggest to store a regular int, and pad it with whatever number of zeros you wish at select time
Try to use query in mysql.
ALTER TABLE table MODIFY COLUMN id INT(3) ZEROFILL;
this may solve your question.

Parsing first line of csv and creating a table inside database

I am downloading new csv's each night using a cron job with PHP. Each csv is normally about the same, possibly one night within a month a field is new. I need to get the new field and append it to the database. I don't know how to get the type of the new field. I saw someone else's question with gettype() but i'm not sure if that would work or not since the data is inside a csv so wouldn't they all be strings when some need to be floats, or ints? How would I go across checking the type?
The second question, is there a way to check if there is not a name inside of a table? For instance, if they add a new field called foo52, and I have foo1 through foo51 in my database, is there a quick way to search for fields that aren't there, or would I have to use a select statement for each one and append it when it's false?
I use MySQL for my database.
Thanks for your help.
The first question on the part about getting the type is the simply try the conversion of the data itself and then seeing if the data is equivalent with a == comparison.
So,
some,data,is,123
After reading in the data you can then try the conversion to various types such as strings, ints, ect...then from that you are able to determine the type of the data.
For the second question you can get the column names by doing:
show columns from db.table_name
Then you can do a simple in_array to test if the new column name is already in the database.
EDIT:
Using array_diff can simplify the finding of the missing/new column names from the CSV.
csv_names = get_csv_column_names();
sql_names = get_sql_column_names();
new_names = array_diff( csv_names, sql_names );
I have found the parsecsv-for-php library very handy for [re|de]constructing CSV data.
For the first question: you can test if it's numeric with is_numeric(). If not, store as string. If yes, create the field as numeric in your database. If you want, you can use regex to check if it's a date or some other datatype you think is required to be stored correctly (i.e. not a a default-text)
for the second question: getting the fieldnames of a table in Postgres is done with the follwoing query
$sql = "SELECT attname FROM pg_catalog.pg_attribute
WHERE attrelid =
(SELECT c.oid FROM pg_catalog.pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = '$this->tableName' AND n.nspname = 'public')
AND attnum > 0
AND NOT attisdropped";
For MySQL, it should be doable with "show columns from db.table_name".
Once you have the fields, use in_array() to check if it exists already...
Note that: you'd probably need to check for all columns in your CSV if they exist already. If not: add a new colum for it. If yes, leave it as is...

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