I got a mysql database column named country_id, like:
country_id
----------
1
2
59
435
2714
What I'm trying to accomplish now is to add leading zero's to each ID, so the result would be:
country_id
----------
0001
0002
0059
0435
2714
Each ID should have max 4 digits. That's it.
Is there any SQL statement I could use in PHPmyAdmin to update this country_id column in the way described above?
Best regards!
Declare ZEROFILL on the column:
mysql> create table foobar (nr integer(4) ZEROFILL);
Query OK, 0 rows affected (0.31 sec)
mysql> INSERT INTO foobar VALUES (1),(12),(123),(1234),(12345);
Query OK, 5 rows affected (0.05 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM foobar;
| 0001
| 0012
| 0123
| 1234
| 12345
If country_id column is character datatype (NOT numeric), then you could prepend zeros and take the rightmost portion:
UPDATE foo SET country_id = RIGHT(CONCATENATE('0000',country_id),4)
UPDATE foo SET country_id = LPAD(country_id, 4, '0')
(NOTE: Either of those statements will result in data loss, if any value of country_id is longer than 4 characters... the first gets the righmost characters, the second will rth get the four leftmost characters, if country_id is over four characters. If a value has e a leading '-' character, that will result in an odd looking value e.g. '00-4'. The LTRIM function is available to remove leading spaces.
If, on the other hand, country_id is a numeric datatype, then you can't really add leading zeros.
For an integer type, you can specify a display length and the ZEROFILL option, e.g.
country_id INT(4) ZEROFILL
But it's up to the client application to make use of the length modifier and the ZEROFILL attribute to do the specified formatting, there's not really anything being done "in the database" with those attributes. (The MySQL command line client will observe those settings, and display the value zero filled to a max of four characters. But other clients are not required to do that.)
You could also cast that value to character and pad it with leading '0' characters, in a query:
SELECT LPAD(country_id, 4, '0') AS country_id
But note that's going to return a character type, not a numeric.
SELECT LPAD(country_id, 4, '0')
FROM your_table
If you can change your DB structure use ZEROFILL
Related
I am trying to create a query to populate unique data from one table into part of another table. The two rows from the source table I'm selecting are of types mediumint(8) and varchar(20). In the destination table I have a Binary(2) and a varchar(20) that I'm trying to populate from the source table. I'm also only selecting the top 100 unique values.
The problem I have is with the mediumint(8) to Binary(2) conversion. I can see all my mediumint(8) values are unique, and they are all less than 200 numerically, but for some reason I can't get them to fit in a 2 byte unique binary column. My query keeps rejecting the insert because it says the values are larger than 2 bytes.
sample query:
select distinct id, part from partsTable
group by id
limit 100;
This comes back with a table that looks kind of like this
id| part
_________
1 | A
2 | B
3 | C
21 | AB
22 | AC
...
I have tried doing things like ( id & 0xFFFF) to force my id column as 2 bytes, and CAST(id as UNSIGNED) or CAST(id as BINARY(2)), but these always truncate the data so that i get duplicate values. Not really sure what I'm missing or how my unique id values that I can see are all unique get translated to non unique values when I try to cast them into binary.
What's even more confusing is as a test I just inserted two records into my destination table:
INSERT into table1 (id, part) VALUES (0xFFFF, 'A');
INSERT into table1 (id, part) VALUES (0xFFFE, 'B');
And then I just wrote a query to see what that data looked like:
SELECT bin(id) as id, hex(id) as hex, part FROM table1;
Which returns a result like:
id | hex | part
__________________
0 | 0xFFFF| A
0 | 0xFFFE| B
So I have no idea what's going on
2 bytes would be a numeric range of 65535. The problem here is the binary data type in MySQL still contains a string, not a number, but with collation of binary instead of something like utf8 as the char data type would. The difference is that the binary data type restricts the value based on the number of bytes rather than the number of characters in the string that it is storing. In other words, a 3 digit value such as 150 as a string would be 3 characters, totaling 3 bytes. So if this value was converted to BINARY(2), it would lose anything past its 2nd byte, making it 15.
Because it stores a string, the binary data type is not restricted to numeric characters (0,1) as you would expect either. So you could make the values fit in a BINARY(2) by using HEX(). HEX(150) would be '96', and would therefore fit in a BINARY(2). You would then have to use UNHEX() to retreive any of these values. If this table already has other values stored in it I doubt this would work for you though.
This is my column
As It's length is specified (smallint(4)), but it does not constrain the range of values
, so how can I constrain that only 4 digit values can be entered in this column
"In query" validation can be done like this:
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table (year INT NOT NULL);
INSERT INTO my_table SELECT 2016 FROM (SELECT 1) n WHERE 2016 BETWEEN 0 AND 9999;
Query OK, 1 row affected (0.00 sec)
SELECT * FROM my_table;
+------+
| year |
+------+
| 2016 |
+------+
INSERT INTO my_table SELECT 20161 FROM (SELECT 1) n WHERE 20161 BETWEEN 0 AND 9999;
Query OK, 0 rows affected (0.00 sec)
SELECT * FROM my_table;
+------+
| year |
+------+
| 2016 |
+------+
From MySQL manual:
MySQL supports an extension for optionally specifying the display width of integer data types in parentheses following the base keyword for the type. For example, INT(4) specifies an INT with a display width of four digits.
The display width does not constrain the range of values that can be stored in the column. Nor does it prevent values wider than the column display width from being displayed correctly. For example, a column specified as SMALLINT(3) has the usual SMALLINT range of -32768 to 32767, and values outside the range permitted by three digits are displayed in full using more than three digits.
So, you cannot limit only 4 digit values in mysql this way. And MySQL does not supports custom CHECK constraints. But you can create trigger like this and check value inside. Note, that SIGNAL works since MySQL 5.5.
When inserting data to mysql via the phpmyadmin page, or via python I've seen something I can't explain:
cur.execute("INSERT INTO 28AA507A0500009E (timestamp, temp) VALUES ('2014-01-04 15:36:30',24.44)")
cur.execute("INSERT INTO 28D91F7A050000D9 (timestamp, temp) VALUES ('2014-01-04 15:36:30',24.44)")
cur.execute("INSERT INTO `28012E7A050000F5` (timestamp, temp) VALUES ('2014-01-04 15:36:30',24.44)")
Notice the last entry with the ` around the table name.
The first 2 entry's work fine without the apostrophe.
I can also put the apostrophes around all the table names and it still works.
Why can I remote the apostrophes from the first 2 lines, and not the 3rd one?
The tables are all created equally.
Edit 1:
In due respect to the following comments:
Your explanation is not entirely accurate. There is no alias in
the INSERT statement. I think that the part of the identifier after
28012E7 is just discarded as MySQL tries convert the identifier to
an integer value! – ypercube
these are table names not column names. – Sly Raskal
Well, MySQL sure have discarded the part of the table name identifier. My intention was to bring forward how a identifier name was interpreted when the system could not find it in the list of accessible table names ( I chose column/expression names in my examples ). As the engine interpreted it as a valid number but not as an identifier to represent a table, it threw an exception.
And I chose SELECT to clarify, why the table identifier was rejected for not putting in back quotes. Because it represents a number, it can't be used as an identifier directly, but should be surrounded with back quotes.
MySQL allows to suffix aliases just after numerics, numeric expressions surrounded by braces or literals. To one's surprise, a space between them is optional.
In your case, 28012E7A050000F5 is a valid exponent form ( 28012E7 ) of number 280120000000 suffixed with alias A050000F5. And hence 28012E7A050000F5 can't be used as a column name without back quotes. See following observations:
mysql> -- select 28012E7 as A050000F5;
mysql> select 28012E7A050000F5;
+--------------+
| A050000F5 |
+--------------+
| 280120000000 |
+--------------+
1 row in set (0.00 sec)
Following are some valid examples:
mysql> -- select ( item_count * price ) as v from orders;
mysql> select ( item_count * price )v from orders;
+-----+
| v |
+-----+
| 999 |
+-----+
1 rows in set (0.30 sec)
mysql> -- select ( 3 * 2 ) as a, 'Ravinder' as name;
mysql> select ( 3 * 2 )a, 'Ravinder'name;
+---+----------+
| a | name |
+---+----------+
| 6 | Ravinder |
+---+----------+
1 row in set (0.00 sec)
Is their an int field in mysql where negative numbers are not allowed? or more specifically if a negative number is inserted into the field it will insert a zero. I ask this because we have a scoring system and we don't allow people to have negative scores. So if their score does reach bellow zero, it will just insert a zero instead. I'm trying to do this without having to query the user's score to check if it will fall bellow zero.
In addition to the DDL change (INT UNSIGNED) that others have recommended, I'd also change your application logic. You say:
I'm trying to do this without having to query the user's score to check if it will fall bellow zero.
You don't have to explicitly check in a separate query:
UPDATE your_table
SET score = GREATEST(score + ?, 0) -- This '?' is the adjustment to the score
WHERE user_id = ?
Now your application cannot UPDATE score to fall below zero, nor will it generate errors or warnings depending on the SQL mode.
Yes. You can create an int field and mark it as UNSIGNED.
From MySQL 5.0 Reference Manual:
INT[(M)] [UNSIGNED] [ZEROFILL]
A normal-size integer. The signed range is -2147483648 to 2147483647.
The unsigned range is 0 to 4294967295.
MySQL has an UNSIGNED qualifier for integer types.
Negative values will be clamped to zero, but will generate a warning:
mysql> create table test ( id int(5) unsigned not null );
Query OK, 0 rows affected (0.05 sec)
mysql> insert into test values (-1), (5), (10);
Query OK, 3 rows affected, 1 warning (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 1
mysql> select * from test;
+----+
| id |
+----+
| 0 |
| 5 |
| 10 |
+----+
3 rows in set (0.01 sec)
If you are running in strict sql mode this would throw an error and an insert/update would fail.
I usally create a user-defined function for this sort of thing. (In this case a very trivial "if (expr1, expr2, expr3)" will do the trick
I just want to know what is the benefit/usage of defining ZEROFILL for INT DataType in MySQL?
`id` INT UNSIGNED ZEROFILL NOT NULL
When you select a column with type ZEROFILL it pads the displayed value of the field with zeros up to the display width specified in the column definition. Values longer than the display width are not truncated. Note that usage of ZEROFILL also implies UNSIGNED.
Using ZEROFILL and a display width has no effect on how the data is stored. It affects only how it is displayed.
Here is some example SQL that demonstrates the use of ZEROFILL:
CREATE TABLE yourtable (x INT(8) ZEROFILL NOT NULL, y INT(8) NOT NULL);
INSERT INTO yourtable (x,y) VALUES
(1, 1),
(12, 12),
(123, 123),
(123456789, 123456789);
SELECT x, y FROM yourtable;
Result:
x y
00000001 1
00000012 12
00000123 123
123456789 123456789
One example in order to understand, where the usage of ZEROFILL might be interesting:
In Germany, we have 5 digit zipcodes. However, those Codes may start with a Zero, so 80337 is a valid zipcode for munic, 01067 is a zipcode of Berlin.
As you see, any German citizen expects the zipcodes to be displayed as a 5 digit code, so 1067 looks strange.
In order to store those data, you could use a VARCHAR(5) or INT(5) ZEROFILL whereas the zerofilled integer has two big advantages:
Lot lesser storage space on hard disk
If you insert 1067, you still get 01067 back
Maybe this example helps understanding the use of ZEROFILL.
It's a feature for disturbed personalities who like square boxes.
You insert
1
23
123
but when you select, it pads the values
000001
000023
000123
It helps in correct sorting in the case that you will need to concatenate this "integer" with something else (another number or text) which will require to be sorted as a "text" then.
for example,
if you will need to use the integer field numbers (let's say 5) concatenated as A-005 or 10/0005
I know I'm late to the party but I find the zerofill is helpful for boolean representations of TINYINT(1). Null doesn't always mean False, sometimes you don't want it to. By zerofilling a tinyint, you're effectively converting those values to INT and removing any confusion ur application may have upon interaction. Your application can then treat those values in a manner similar to the primitive datatype True = Not(0)
mysql> CREATE TABLE tin3(id int PRIMARY KEY,val TINYINT(10) ZEROFILL);
Query OK, 0 rows affected (0.04 sec)
mysql> INSERT INTO tin3 VALUES(1,12),(2,7),(4,101);
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM tin3;
+----+------------+
| id | val |
+----+------------+
| 1 | 0000000012 |
| 2 | 0000000007 |
| 4 | 0000000101 |
+----+------------+
3 rows in set (0.00 sec)
mysql>
mysql> SELECT LENGTH(val) FROM tin3 WHERE id=2;
+-------------+
| LENGTH(val) |
+-------------+
| 10 |
+-------------+
1 row in set (0.01 sec)
mysql> SELECT val+1 FROM tin3 WHERE id=2;
+-------+
| val+1 |
+-------+
| 8 |
+-------+
1 row in set (0.00 sec)
ZEROFILL
This essentially means that if the integer value 23 is inserted into an INT column with the width of 8 then the rest of the available position will be automatically padded with zeros.
Hence
23
becomes:
00000023
When used in conjunction with the
optional (nonstandard) attribute
ZEROFILL, the default padding of
spaces is replaced with zeros. For
example, for a column declared as
INT(4) ZEROFILL, a value of 5 is
retrieved as 0005.
http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html
If you specify ZEROFILL for a numeric column, MySQL automatically adds the UNSIGNED attribute to the column.
Numeric data types that permit the UNSIGNED attribute also permit SIGNED. However, these data types are signed by default, so the SIGNED attribute has no effect.
Above description is taken from MYSQL official website.