Mysql enum not searching record without quote value - mysql

I have table field with enum enum('0','1','2','3','4','5','6').
In query when I try with IN (1) it is not working but when I use IN ("1") it is working.
If I use In (1,2) it is working.
So when there is one value in "IN" clause then it should work without quote

ENUM values are defined and stored as strings. They can be accessed via their string value or via their numeric index value (which starts at 1 and not 0).
Your enum values start at '0' which would have a numeric index value of 1. So, it would be possible to get some data back from your query using IN(1,2) but those numbers will be treated as the index and you will actually get data returned for records where the enum values are '2' and '3' (probably not what you think you are getting back).
IN(1) doesn't work because you have no data with an index value of 1 (emum value = '0')
IN('1') does work because you do have data with an enum value of '1'
Try this for a practical example
http://sqlfiddle.com/#!9/3993b/1
or read the section on Handling of Enumeration Literals in the mysql documentation

You can use values as string or integer, IN() function support both types.
The IN operator allows you to specify multiple values in a WHERE clause.
Usually IN() function is using for multiples values but it does support single value also. For me all queries are working
SELECT * FROM `your_table` WHERE `id` IN('4') // String Number
SELECT * FROM `your_table` WHERE `id` IN('4','2','1') // String Multiple Number
SELECT * FROM `your_table` WHERE `id` IN(1) // Single Integer
SELECT * FROM `your_table` WHERE `id` IN(1,2,4) // Multiple Integer

Avoid using number as 'enumeration values'
Doucumenation quotes-We strongly recommend that you do not use numbers as enumeration values, because it does not save on storage over the appropriate TINYINT or SMALLINT type, and it is easy to mix up the strings and the underlying number values (which might not be the same) if you quote the ENUM values incorrectly. If you do use a number as an enumeration value, always enclose it in quotation marks. If the quotation marks are omitted, the number is regarded as an index. See Handling of Enumeration Literals to see how even a quoted number could be mistakenly used as a numeric index value.'
Link- https://dev.mysql.com/doc/refman/5.7/en/enum.html#enum-limits

enum supports accessing values either by numeric index of values or values that are directly quoted.
As per MySQL documentation on ENUM:
... strongly recommend that you do not use numbers as enumeration values,
because it does not save on storage over the appropriate TINYINT or SMALLINT type,
and it is easy to mix up the strings and the underlying number values
(which might not be the same) if you quote the ENUM values incorrectly.
If you do use a number as an enumeration value, always enclose it in quotation marks.
If the quotation marks are omitted, the number is regarded as an index.
Examples:
mysql> drop table if exists so_q48786040;
mysql> CREATE TABLE so_q48786040(e ENUM('6', '5', '4', '3', '2', '1', '0'));
mysql> INSERT INTO so_q48786040 VALUES( 2 ), ( 4 ), ( 7 ), ( '6' );
Query OK, 4 rows affected (0.05 sec)
Records: 4 Duplicates: 0 Warnings: 0
Selecting all rows, returns values 5,3,0,6
mysql> SELECT * FROM so_q48786040;
+------+
| e |
+------+
| 5 |
| 3 |
| 0 |
| 6 |
+------+
4 rows in set (0.00 sec)
Selecting at specific indices. Results will be in the order of enum indices defined.
mysql> SELECT * FROM so_q48786040 WHERE e IN( 7, 4 );
+------+
| e |
+------+
| 3 | -- <--- at index 4
| 0 | -- <--- at index 7
+------+
2 rows in set (0.00 sec)
Selecting at specific quoted literals. Results will be in the order of enum indices defined.
mysql> SELECT * FROM so_q48786040 WHERE e IN( '6', '3', '0' );
+------+
| e |
+------+
| 3 |
| 0 |
| 6 |
+------+
3 rows in set (0.00 sec)
Selecting a non existing entry. Returns empty set as '4' was not inserted
mysql> SELECT * FROM so_q48786040 WHERE e IN( '4' );
Empty set (0.00 sec)
NOTE:
It is suggested to define empty literals at index 0.
The index of the NULL value is NULL.

Related

Small Int Type Length

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.

Connot select rows without double quote using ENUM variable type in MySQL

How to select rows without using the double quotes("1").
I am design the status column in enum type.
status
enum('0', '1')
My Query:
SELECT * FROM `user` WHERE activation_key='123456' AND status="1";
Result :
Display 1 row
I am Try :
SELECT * FROM `user` WHERE activation_key='123456' AND status=1;
Result :
Display 0 row
Is it possible to get the data without double or single quotes in status column?
I am a beginner of MYSQL, Sorry for my bad question!
An enumeration value must be a quoted string literal. And to query a string you must enclose it in quotes.
If you make enumeration values that look like numbers, it is easy to mix up the literal values with their internal index numbers.
numbers ENUM('0','1','2')
If you store 2, it is interpreted as an index value, and becomes '1'
(the value with index 2). If you store '2', it matches an enumeration
value, so it is stored as '2'. If you store '3', it does not match any
enumeration value, so it is treated as an index and becomes '2' (the
value with index 3).
mysql> INSERT INTO t (numbers) VALUES(2),('2'),('3');
mysql> SELECT * FROM t;
+---------+
| numbers |
+---------+
| 1 |
| 2 |
| 2 |
+---------+
More details ENUM in MySQL

mysql strange behavior when inserting data

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)

mysql prevent negative numbers

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

What is the benefit of zerofill in MySQL?

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.