Getting the wrong answer when getting the sum of column name - mysql

I have a problem in getting the sum of one of my column names in database (PRICE). If I insert 1000.00 and 3600.00 to get the sum of them, I am getting 4.00 instead of 4600.00. But when the total is below 1000 I get the correct answer.

It appears that your price_per_case column is char or varchar column rather than a numeric column such as decimal(10,2). So, it is converting the column to double but ignoring everything after the , character (and probably issuing warnings during the conversion). You can verify this by trying the following:
select '1,234' + '3,456';
You will end up with 4;
You should try running:
update ordered set price_per_case = replace(price_per_case, ',', ''); /* get rid of commas */
Then you should change the type of this column to decimal(10,2) or some appropriate precision.

Maybe the machine when you are programming have different “Locale” of MySql Server (are both in the same machine)?
In this case also format currency/double/decimal is different.
To avoid that you need to change Locale in you .NET method/sub/function before/into you get query result
Threading.Thread.CurrentThread.CurrentCulture = New CultureInfo("it-IT")
Threading.Thread.CurrentThread.CurrentUICulture = New CultureInfo("it-IT")
or change Locale in MySql
SET lc_time_names = 'it_IT'; Here continue your query
In this example I have used Italian Locale

Related

How to update exact decimal value in mysql database

I am working with mysql. I created a column in database called "balance" and the datatype for this column is "DECIMAL(12,6)".
So whenever I try to update 4 digits after the decimal point then the last two digits are showing random values (e.g. balance is showing 4444.888672 for the following query).
Here is my current query
UPDATE `table` SET `balance` = '4444.8888' WHERE `token_address` = 'abc123'
Sounds like common float overflow issue, where decimal part does not fit into memory and is cut off.
In our system we use INT's instead. So you would save into database 44448888000 and in PHP you would parse it as $row['balance'] / 1000000

How to select one column value, normalize and put to another column in mysql?

In my table, I've got a column call mobile and I need this mobile field value to be normalized and save to another column call formatted_phone. For this purpose, I am using the below MySQL query and unfortunately, it is not working. I am putting my query here, please someone correct it. Thank you.
UPDATE hiring_detail
SET formatted_phone = replace(replace(
replace(replace(replace(replace(mobile,'-',''),'+',''),')',''),'(',''),' ',''),'.','')
WHERE mobile IS NOT NULL;
Error what it throws:
SQL Error (1265):Data truncated for column 'formatted_phone' at row 3
mobile column: varchar 50
formatted_phone: bigint 15
Usually, beofre blindly executing UPDATE commands, we do a simply What If analysis first, just run the query as a SELECT so you can inspect the output and importantly, you can compare it to the existing values:
http://sqlfiddle.com/#!9/47723a/2
SELECT mobile, formatted_phone
, REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(mobile,'-',''),'+',''),')',''),'(',''),' ',''),'.','') as test
FROM hiring_detail
WHERE mobile IS NOT NULL;
If that logic works for you (and it does in my tests) then there should be no issue with your UPDATE logic.
UPDATE:
If your error is
SQL Error (1265):Data truncated for column 'formatted_phone' at row 3
Then that means that your formatted phone numbers are longer than the column width for formatted_phone. If you know what the length is, you can truncate your formatted numbers, but with phone numbers, if we remove the actual number, this usually results in phone numbers that cannot be called.
I would recommend instead that you increase the width of the formatted_phone field.
This is an example of a forced truncation:
UPDATE hiring_detail
SET formatted_phone = RIGHT(replace(replace(
replace(replace(replace(replace(mobile,'-',''),'+',''),')',''),'(',''),' ',''),'.',''),10)
WHERE mobile IS NOT NULL;
Update #2
given that the column is an int, we need to convert the value into an integer.
UPDATE hiring_detail
SET formatted_phone = CAST(replace(replace(
replace(replace(replace(replace(mobile,'-',''),'+',''),')',''),'(',''),' ',''),'.','') as UNSIGNED INT)
WHERE mobile IS NOT NULL;
Warning: It is NOT advisable to store phone numbers as integers, the leading zeros can be significant in area codes in many localities, by storing as a numeric value this can have significant effects and can result in los of data. It also makes it hard to search for partial matches on the numbers. Almost all operations that you can think of (including sorting) on phone numbers will involve string manipulations, not mathematical or numerical.

Select statement returns data although given value in the where clause is false

I have a table on my MySQL db named membertable. The table consists of two fields which are memberid and membername. The memberid field has the type of integer and uses auto_increment function starting from 2001. The membername table has the type of varchar.
The membertable has two records with the same order as described above. The records look like this :
memberid : 2001
membername : john smith
memberid : 2002
membername : will smith
I found something weird when I ran a SELECT statement against the memberid field. Running the following statement :
SELECT * FROM `membertable` WHERE `memberid` = '2001somecharacter'
It returned the first data.
Why did that happen? There's no record with memberid = 2001somecharacter. It looks like MySQL only search the first 4 character (2001) and when It's found related data, which is the returned data above, it denies the remaining characters.
How could this happen? And is there any way to turn off this behavior?
--
membertable uses innodb engine
This happens because mysql tries to convert "2001somecharacter" into a number which returns 2001.
Since you're comparing a number to a string, you should use
SELECT * FROM `membertable` WHERE CONVERT(`memberid`,CHAR) = '2001somecharacter';
to avoid this behavior.
OR to do it properly, is NOT put your search variable in quotes so that it has to be a number otherwise it'll blow up because of syntax error and then in front end making sure it's a number before passing in the query.
sqlfiddle
Your finding is an expexted MySQL behaviour.
MySQL converts a varchar to an integer starting from the beginning. As long as there are numeric characters wich can easily be converted, they are icluded in the conversion process. If there's a letter, the conversion stops returning the integer value of the numeric string read so far...
Here's some description of this behavior on the MySQL documentation Site. Unfortunately, it's not mentioned directly in the text, but there's an example which exactly shows this behaviour.
MySQL is very liberal in converting string values to numeric values when evaluated in numeric context.
As a demonstration, adding 0 causes the string to evaluated in a numeric context:
SELECT '2001foo' + 0 --> 2001
, '01.2-3E' + 0 --> 1.2
, 'abc567g' + 0 --> 0
When a string is evaluated in a numeric context, MySQL reads the string character by character, until it encounters a character where the string can no longer be interpreted as a numeric value, or until it reaches the end of the string.
I don't know of a way to "turn off" or disable this behavior. (There may be a setting of sql_mode that changes this behavior, but likely that change will impact other SQL statements that are working, which may stop working if that change is made.
Typically, this kind of check of the arguments is done in the application.
But if you need to do this in the SELECT statement, one option would be cast/convert the column as a character string, and then do the comparison.
But that can have some significant performance consequences. If we do a cast or convert (or any function) on a column that's in a condition in the WHERE clause, MySQL will not be able to use a range scan operation on a suitable index. We're forcing MySQL to perform the cast/convert operation on every row in the table, and compare the result to the literal.
So, that's not the best pattern.
If I needed to perform a check like that within the SQL statement, I would do something like this:
WHERE t.memberid = '2001foo' + 0
AND CAST('2001foo' + 0 AS CHAR) = '2001foo'
The first line is doing the same thing as the current query. And that can take advantage of a suitable index.
The second condition is converting the same value to a numeric, then casting that back to character, and then comparing the result to the original. With the values shown here, it will evaluate to FALSE, and the query will not return any rows.
This will also not return a row if the string value has a leading space, ' 2001'. The second condition is going to evaluate as FALSE.
When comparing an INT to a 'string', the string is converted to a number.
Converting a string to a number takes as many of the leading characters as it can and still be a number. So '2001character' is treated as the number 2001.
If you want non-numeric characters in member_id, make it VARCHAR.
If you want only numeric ids, then reject '200.1character'

Remove trailing decimal values to 1 place in sql server 2008 with money format

I have number in DB column and i want to format this with money,decimal data types.
my query is like below,
SELECT CONVERT(VARCHAR,CAST(CAST(CAST(HouseholdCoverage AS DECIMAL(10,1))/ 12 AS DECIMAL(10,1))
AS money),1) AS HouseholdGoodsInsuredAmount FROM Table
HouseholdCoverage = 1175012
My query returns the value like below,
97,917.70
but i want result as
97,917.7 (only 1 number after decimal places).
If i cast the value as float i am getting error.
I know i can use parsename to separate the values after decimal place and add it again with few modifications. But that is not good i feel.
As well as i know this has to be done in C# application, but this query is already written in sql server 2008, i just want modify it according to requirements.
I just figured it out myself after doing some extensive research.. but dont know performance will be good or bad
SELECT LEFT(CONVERT(VARCHAR,CAST(CAST(CAST(HouseholdCoverage AS DECIMAL(10,1))/ 12 AS DECIMAL(10,1))AS money),1),
len(CONVERT(VARCHAR,CAST(CAST(CAST(HouseholdCoverage AS DECIMAL(10,1))/ 12 AS DECIMAL(10,1))AS money),1))-1)
AS HouseholdGoodsInsuredAmount FROM Table
Now the result is as i expected with 1 decimal places after decimal point,
97,917.7
Just keep is simple. Divide your number by a decimal number and cast the answer as DECIMAL(10,1)
DECLARE #HouseholdCoverage BIGINT = 1175012
SELECT CAST(#HouseholdCoverage/128.0 AS DECIMAL(10,1))
DECIMAL(10,1) will make sure that there will be only 1 number after precision(.)

"Data too long for column" - why?

I've written a MySQL script to create a database for hypothetical hospital records and populate it with data. One of the tables, Department, has a column named Description, which is declared as type varchar(200). When executing the INSERT command for Description I get an error:
error 1406: Data too long for column 'Description' at row 1.
All the strings I'm inserting are less than 150 characters.
Here's the declaration:
CREATE TABLE Department(
...
Description varchar(200)
...);
And here's the insertion command:
INSERT INTO Department VALUES
(..., 'There is some text here',...), (..., 'There is some more text over here',...);
By all appearances, this should be working. Anyone have some insight?
Change column type to LONGTEXT
I had a similar problem when migrating an old database to a new version.
Switch the MySQL mode to not use STRICT.
SET ##global.sql_mode= 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Error Code: 1406. Data too long for column - MySQL
There is an hard limit on how much data can be stored in a single row of a mysql table, regardless of the number of columns or the individual column length.
As stated in the OFFICIAL DOCUMENTATION
The maximum row size constrains the number (and possibly size) of columns because the total length of all columns cannot exceed this size. For example, utf8 characters require up to three bytes per character, so for a CHAR(255) CHARACTER SET utf8 column, the server must allocate 255 × 3 = 765 bytes per value. Consequently, a table cannot contain more than 65,535 / 765 = 85 such columns.
Storage for variable-length columns includes length bytes, which are assessed against the row size. For example, a VARCHAR(255) CHARACTER SET utf8 column takes two bytes to store the length of the value, so each value can take up to 767 bytes.
Here you can find INNODB TABLES LIMITATIONS
in mysql if you take VARCHAR then change it to TEXT bcoz its size is 65,535
and if you can already take TEXT the change it with LONGTEXT only if u need more then 65,535.
total size of LONGTEXT is 4,294,967,295 characters
Varchar has its own limits. Maybe try changing datatype to text.!
Turns out, as is often the case, it was a stupid error on my part. The way I was testing this, I wasn't rebuilding the Department table after changing the data type from varchar(50) to varchar(200); I was just re-running the insert command, still with the column as varchar(50).
If your source data is larger than your target field and you just want to cut off any extra characters, but you don't want to turn off strict mode or change the target field's size, then just cut the data down to the size you need with LEFT(field_name,size).
INSERT INTO Department VALUES
(..., LEFT('There is some text here',30),...), (..., LEFT('There is some more text over here',30),...);
I used "30" as an example of your target field's size.
In some of my code, it's easy to get the target field's size and do this. But if your code makes that hard, then go with one of the other answers.
For me, I defined column type as BIT (e.g. "boolean")
When I tried to set column value "1" via UI (Workbench), I was getting a "Data too long for column" error.
Turns out that there is a special syntax for setting BIT values, which is:
b'1'
With Hibernate you can create your own UserType. So thats what I did for this issue. Something as simple as this:
public class BytesType implements org.hibernate.usertype.UserType {
private final int[] SQL_TYPES = new int[] { java.sql.Types.VARBINARY };
//...
}
There of course is more to implement from extending your own UserType but I just wanted to throw that out there for anyone looking for other methods.
Very old question, but I tried everything suggested above and still could not get it resolved.
Turns out that, I had after insert/update trigger for the main table which tracked the changes by inserting the record in history table having similar structure. I increased the size in the main table column but forgot to change the size of history table column and that created the problem.
I did similar changes in the other table and error is gone.
I try to create a table with a field as 200 characters and I've added two rows with early 160 characters and it's OK. Are you sure your rows are less than 200 characters?
Show SqlFiddle
There was a similar problem when storing a hashed password into a table. Changing the maximum column length didn't help. Everything turned out to be simple. It was necessary to delete the previously created table from the database, and then test the code with new values ​​of the allowable length.
If you re using type: DataTypes.STRING, then just pass how long this string can be like DataTypes.STRING(1000)
In my case this error occurred due to entering data a wrong type for example: if it is a long type column, i tried to enter in string type. so please check your data that you are entering and type are same or not
For me, I try to update column type "boolean" value
When I tried to set column value 1 MySQL Workbench, I was getting a "Data too long for column" error.
So for that there is a special syntax for setting boolean values, which is:
UPDATE `DBNAME`.`TABLE_NAME` SET `FIELD_NAME` = false WHERE (`ID` = 'ID_VALUE'); //false for 0
UPDATE `DBNAME`.`TABLE_NAME` SET `FIELD_NAME` = true WHERE (`ID` = 'ID_VALUE'); //true for 1
I had a different problem which gave the same error so I'll make a quick recap as this seems to have quite different sources and the error does not help much to track down the root cause.
Common sources for INSERT / UPDATE
Size of value in row
This is exactly what the error is complaining about. Maybe it's just that.
You can:
increase the column size: for long strings you can try to use TEXT, MEDIUMTEXT or LONGTEXT
trim the value that is too long: you can use tools from the language you're using to build the query or directly in SQL with LEFT(value,size) or RIGHT(...) or SUBSTRING(...)
Beware that there is a maximum row size in a MySQL table as reported by this answer. Check documentation and InnoDB engine limitations.
Datatype Mismatch
One or more rows are of the wrong datatype.
common sources of error are
ENUM
BIT: don't use 1 but b'1'
Data outlier
In a long list of insert one can easily miss a row which has a field not adhering to the column typing, like an ENUM generated from a string.
Python Django
Check if you have sample_history enabled, after a change in a column size it must be updated too.