Here is my table:
// table
+----+--------+
| id | number |
+----+--------+
| 1 | 123 |
| 2 | 123. |
| 3 | 12.3 |
+----+--------+
I want this:
// newtable
+----+--------+
| id | number |
+----+--------+
| 1 | 123 |
| 2 | 123 |
| 3 | 12.3 |
+----+--------+
How can I do that?
I can do that like this: (But I'm searching for faster and better approach)
// Not tested, But I think this works!
SELECT
id,
IF(RIGHT(number,1) == '.', REPLACE(number, '.', ''), number)
FROM table
// also I can use CAST(number as unsigned) instead of REPLACE(number, '.', '')
Well, is there any better solution? (without IF-statement)
SELECT id, CONVERT(number, DECIMAL(10,6)) FROM test
remove last corresponding characters if exist
SELECT id, TRIM(TRAILING '.' FROM number) FROM test
use this if you want to change the data in the table
mysql> CREATE TABLE test(
-> id INT(1),
-> number VARCHAR(5)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> INSERT INTO test
-> VALUES(1, '123'),
-> (2, '123.'),
-> (3, '12.3');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM test;
+------+--------+
| id | number |
+------+--------+
| 1 | 123 |
| 2 | 123. |
| 3 | 12.3 |
+------+--------+
3 rows in set (0.00 sec)
mysql> UPDATE test
-> SET number=REPLACE(number, '.', '')
-> WHERE RIGHT(number,1) = '.';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM test;
+------+--------+
| id | number |
+------+--------+
| 1 | 123 |
| 2 | 123 |
| 3 | 12.3 |
+------+--------+
3 rows in set (0.00 sec)
and use this if you want just to get the data in this form
mysql> DROP TABLE IF EXISTS test;
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE test(
-> id INT(1),
-> number VARCHAR(5)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> INSERT INTO test VALUES
-> (1, '123'),
-> (2, '123.'),
-> (3, '12.3')
-> ;
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM test;
+------+--------+
| id | number |
+------+--------+
| 1 | 123 |
| 2 | 123. |
| 3 | 12.3 |
+------+--------+
3 rows in set (0.00 sec)
mysql> SELECT
-> id,
-> CASE
-> WHEN RIGHT(number,1) = '.' THEN floor(number)
-> ELSE number
-> END AS number
-> from test;
+------+--------+
| id | number |
+------+--------+
| 1 | 123 |
| 2 | 123 |
| 3 | 12.3 |
+------+--------+
3 rows in set (0.00 sec)
Related
Dropping or truncating a table resets the counter(AUTO_INCREMENT), but deleting selected rows (with a WHERE clause) doesn’t reset the counter.
I want it to continue it from the point where rows were deleted.
Is there any way to reset the counter? Please follow the example below for better understanding.
mysql> create table dummy(id int NOT NULL AUTO_INCREMENT PRIMARY KEY);
Query OK, 0 rows affected (2.09 sec)
mysql> insert into dummy values (),(),(),(),(),();
Query OK, 6 rows affected (0.19 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> select * from dummy;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
+----+
6 rows in set (0.00 sec)
mysql> delete from dummy where id>4;
Query OK, 2 rows affected (0.23 sec)
mysql> select * from dummy;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
+----+
4 rows in set (0.00 sec)
mysql> insert into dummy values (),(),(),(),(),();
Query OK, 6 rows affected (0.18 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> select * from dummy;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 7 |
| 8 |
| 9 |
| 10 |
| 11 |
| 12 |
+----+
10 rows in set (0.00 sec)
What I want:
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
+----+
We can query alter table dummy AUTO_INCREMENT=1; after delete statement;
So, as soon as we add new values to the table, it will check in the existing table, what value should be assign to the id starting from 0, and will assign the one which is exactly 1 greater than the max id of the table.
So, it will be like:
mysql> delete from dummy where id>4;
Query OK, 2 rows affected (0.14 sec)
mysql> select * from dummy;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
+----+
4 rows in set (0.00 sec)
mysql> alter table dummy AUTO_INCREMENT=1;
Query OK, 0 rows affected (0.21 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> insert into dummy values (),(),(),(),(),();
Query OK, 6 rows affected (0.18 sec)
Records: 6 Duplicates: 0 Warnings: 0
And we will get in sequential form:
select * from dummy;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
+----+
Thanks #jspcal
I am learning InnoDB mvcc now and i have try a test show as follows:
Mysql version:
[root#mysql-test ~]# mysql --version
mysql Ver 15.1 Distrib 5.5.52-MariaDB, for Linux (x86_64) using readline 5.1
table schema:
MariaDB [liruifeng]> show create table test_a;
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| test_a | CREATE TABLE `test_a` (
`id` int(11) NOT NULL DEFAULT '0',
`a` char(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
then init with data like this:
MariaDB [liruifeng]> select * from test_a;
+----+------+
| id | a |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+------+
3 rows in set (0.00 sec)
and at first i have open two session in different terminals, the test step show as bellows:
t1:
MariaDB [liruifeng]> start transaction;
Query OK, 0 rows affected (0.00 sec)
MariaDB [liruifeng]> select * from test_a;
+----+------+
| id | a |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+------+
3 rows in set (0.00 sec)
t2:
MariaDB [liruifeng]> insert into test_a values (4,4);
Query OK, 1 row affected (0.01 sec)
MariaDB [liruifeng]> select * from test_a;
+----+------+
| id | a |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
+----+------+
4 rows in set (0.00 sec)
t1:
MariaDB [liruifeng]> select * from test_a;
+----+------+
| id | a |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+------+
3 rows in set (0.00 sec)
MariaDB [liruifeng]> update test_a set a = 444 where id = 4;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [liruifeng]> select * from test_a;
+----+------+
| id | a |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 444 |
+----+------+
4 rows in set (0.00 sec)
it makes me puzzled that why a t1 can update the row insert by t2 before t1 has committed? my tx_isolation level is repeatable read and why will this update sql works?
my isolation show as bellows:
MariaDB [liruifeng]> show variables like 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
thanks in advances :)
REPEATABLE-READ says that the select * from test_a; will say the same thing until t1 COMMITs. The fact that the UPDATE can see row 4 but the identical SELECT cannot is weird, but valid.
this is strange, in my experiment with auto-commit = false the update will block because of a record X lock on the inserted entry.
I want to have an empty field on a MySQL Numeric field. If I define the field to allow a NULL value it defaults to 0.00. Sometimes for this row item I prefer no value. I could probably create a different table to track these few items, but at this point I prefer a one table solution.
Because you did this with DEFAULT. Don't do that:
create table t1
( id int auto_increment primary key,
thing varchar(100) not null,
anInt NUMERIC(5,2) NULL DEFAULT 0
);
insert t1(thing) values ('fish');
select * from t1;
+----+-------+-------+
| id | thing | anInt |
+----+-------+-------+
| 1 | fish | 0.00 |
+----+-------+-------+
Works for me on mysql 5.7.12:
mysql> create table X (a double null);
Query OK, 0 rows affected (0.01 sec)
mysql> desc X;
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| a | double | YES | | NULL | |
+-------+--------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> alter table X add column b int;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc X;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| a | double | YES | | NULL | |
| b | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into X (a) values (1.3);
Query OK, 1 row affected (0.00 sec)
mysql> insert into X (b) values (1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from X;
+------+------+
| a | b |
+------+------+
| 1.3 | NULL |
| NULL | 1 |
+------+------+
2 rows in set (0.00 sec)
On running the following statements:
set autocommit = false;
start transaction;
insert into test_table (id,name) values('6','iqbal bano');
The entry gets inserted into the database, although I didn't issue the command commit. Is this behavior natural to mysql? If yes, why is it so? To my surprise, if I run 3 statements as:
set autocommit = false;
start transaction;
insert into test_table (id,name) values('7','chitra singh');
insert into test_table (id,name) values('8',nayaara);
The third statement, returns an error (because nayaara had to wrapped inside the quotes) but, the previous insert succeeds and entry with id 7 is created into the database. What is the reason for this? Is this the way the transaction will proceed?
Note: Autocommit is set to false, as shown in the above statements.
If you set the auto-commit to false and the inserts go through, its part of the transaction but doesn't get committed to the database. If you were to restart the database the inserts would be lost; the transaction is rolledback since you did not say commit. However if you commit and then restart the records are not lost.
mysql> set autocommit=false;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test (id) values (5),(6),(7),(8);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from test;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
+------+
8 rows in set (0.00 sec)
mysql> exit
Bye
mysql> select * from test;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
+------+
4 rows in set (0.00 sec)
mysql> insert into test (id) values (5),(6),(7),(8);
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from test;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
+------+
8 rows in set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
+------+
8 rows in set (0.00 sec)
MySQL provides 2 ways to check truth value of boolean columns, those are column_variable = true and column_variable is true. I created a table, inserted few values & tried a few select statements. Here are the results:
First I created this table:
mysql> create table bool_test (
-> id int unsigned not null auto_increment primary key,
-> flag boolean );
Query OK, 0 rows affected (0.13 sec)
Then I inserted 4 rows:
mysql> insert into bool_test(flag) values (true),(false),(9),(null);
mysql> select * from bool_test;
+----+------+
| id | flag |
+----+------+
| 1 | 1 |
| 2 | 0 |
| 3 | 9 |
| 4 | NULL |
Here are all the select queries I fired on this table:
mysql> select * from bool_test where flag;
+----+------+
| id | flag |
+----+------+
| 1 | 1 |
| 3 | 9 |
+----+------+
2 rows in set (0.49 sec)
mysql> select * from bool_test where flag = true;
+----+------+
| id | flag |
+----+------+
| 1 | 1 |
+----+------+
1 row in set (0.02 sec)
mysql> select * from bool_test where flag is true;
+----+------+
| id | flag |
+----+------+
| 1 | 1 |
| 3 | 9 |
+----+------+
2 rows in set (0.04 sec)
mysql> select * from bool_test where flag = false;
+----+------+
| id | flag |
+----+------+
| 2 | 0 |
+----+------+
1 row in set (0.01 sec)
mysql> select * from bool_test where flag is false;
+----+------+
| id | flag |
+----+------+
| 2 | 0 |
+----+------+
1 row in set (0.00 sec)
mysql> select * from bool_test where !flag;
+----+------+
| id | flag |
+----+------+
| 2 | 0 |
+----+------+
1 row in set (0.00 sec)
mysql> select * from bool_test where not flag;
+----+------+
| id | flag |
+----+------+
| 2 | 0 |
+----+------+
1 row in set (0.00 sec)
mysql> select * from bool_test where flag != true;
+----+------+
| id | flag |
+----+------+
| 2 | 0 |
| 3 | 9 |
+----+------+
2 rows in set (0.00 sec)
mysql> select * from bool_test where flag is not true;
+----+------+
| id | flag |
+----+------+
| 2 | 0 |
| 4 | NULL |
+----+------+
2 rows in set (0.00 sec)
mysql> select * from bool_test where flag != false;
+----+------+
| id | flag |
+----+------+
| 1 | 1 |
| 3 | 9 |
+----+------+
2 rows in set (0.04 sec)
mysql> select * from bool_test where flag is not false;
+----+------+
| id | flag |
+----+------+
| 1 | 1 |
| 3 | 9 |
| 4 | NULL |
+----+------+
3 rows in set (0.00 sec)
My Question is: when is it advisable to use is/is not and when is it advisable to use =/!= with true/false ? Which one is vendor independent?
MySQL is actually fooling you. It doesn't have a boolean column type at all:
BOOL, BOOLEAN
These types are synonyms for TINYINT(1). A value of zero is considered
false. Nonzero values are considered true:
Also, the boolean literals are not such:
The constants TRUE and FALSE evaluate to 1 and 0, respectively.
Considering that:
Many database systems do not have booleans either (not at least in standard SQL and column types)
MySQL doesn't have an easy way to enforce 0 or 1 in BOOLEAN
My conclusion would be:
You'll have to use WHERE IS flag or just WHERE flag because = simply doesn't work correctly. Which one, is possibly a matter of preference.
Whatever you choose, no option will be vendor independent. For instance, Oracle won't even run either of them.
Edit: if cross-platform is a must, I'd go for this:
WHERE flag=0
WHERE flag<>0
I'm sure we've all done it lots of times.
If the flag column is indexed and all values are either 0 or 1, where flag = true is much faster than where flag is true.
During our testing, is true resulted in a “full table scan” and took 1.121 seconds, while = true was executed with “key lookup” and only took 0.167 seconds. The table had about 3 million rows.