Strange Behavior of MySQL MAX function - mysql

Suppose In my MySQL table there are no row inserted yet.
CREATE TABLE Users (
SerialNo INT(9) NOT NULL AUTO_INCREMENT,
UserID INT(9) NOT NULL,
PRIMARY KEY (SerialNo)
);
When I run the following MySQL statement:
INSERT INTO Users(UserID) SELECT MAX(UserID)+1 FROM Users;
The table looks like the following picture:
Image Link: https://s1.postimg.org/4r2xcc7ajj/z_Ii_A-_KUp_Tzio_-00_PBL0_KQ.png
Can anyone tell me why MAX(UserID)+1 setting 0 instead of 1?

0 is the default value used for an int field without a default
specified.
Inserting null values into not null fields usually results
in the field given the null value being assigned it's default value
instead.
Most aggregate functions only return null only if the
encounter no non-null values.
Since the table is empty, MAX returns null, and NULL + 1 is NULL.
You're inserting null into an integer field without a default value specified.
Edit: To insert 1 in such cases use IFNULL(MAX(UserId),0)+1

As mysql manual on max() says: max() returns null if there is no matching record. If there is no record at all in the table, then max(userid) returns null.
null + 1 will also be null. So, you query tries to insert null into your table.
Your mysql is configured with strict mode turned off, therefore when you try to insert a null value into a non-null field, mysql silently converts the null to the fields implicit default value. This happens to be 0 for an integer field.
If strict mode were turned on, then you would get an error message for trying to insert an illegal value into your table. This way, you only get a warning.
Btw, you should turn strict mode on.

Related

Making value required in insert Statement

I want to make ItemCode value in my table required when using the insert statement, I thought of using a NOT NULL constraint but I do not know if that is correct. Here is the structure of my table
CREATE TABLE Item
(
ID INT auto_increment,
ItemCode VARCHAR(10) unique NOT NULL,
ItemDescription VARCHAR(50),
Price DECIMAL(4,2) DEFAULT 0,
PRIMARY KEY(ID)
);
Using not null will only enforce a value for this field when the record is saved to the database. If the user enters a string of spaces, it will still get saved. You need to put data validation rules in the front end of your application.
By default, columns in SQL accept NULL values. And, if a value is not provided in an INSERT, then the default is NULL.
When you declare a DEFAULT value ("constraint") for a column, then you can change the value that is inserted, when no value is provided. You haven't declared a DEFAULT, so NULL is used.
Then, NOT NULL prevents a NULL value from being inserted. So, if no value is provided, a DEFAULT value will be used. However, with no DEFAULT an error will occur -- violating the NOT NULL constraint.
In short, your definition does what you want.
Note: Triggers can affect this functionality, so the above assumes that triggers do not use the value in that column.

MYSQL : null behavior against integer check

Lets say i have this table:
CREATE TABLE `offers` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`status` int(11) DEFAULT NULL,
)
and fill it with this record:
INSERT INTO offers (status) VALUES (null);
now run this query :
DELETE FROM offers WHERE STATUS <> 3
I'm expecting the latest record get removed from table but it doesn't.why? and whats the correct way to solve such issues?
In SQL the value NULL is very special! Pretty much any expression that has a NULL value in it will evaluate to NULL. That means that when you do the STATUS<>3, if STATUS is NULL, the result is NULL, which when used directly as a truth value is false. So, the expression WHERE STATUS <> 3 selects rows that have a value other than 3. Rows with the value 3 and rows with no value (i.e. NULL) will not be selected. The only time a comparison of a variable that's NULL can be true is if you use the IS NULL comparison, or related special constructs. You probably want to review the relevant sections of the manual, if you actually want to use NULL in a constructive fashion.
This is answered in MySQL's documentation about NULL. The integer comparison you are doing does not satisfy NULL value. NULL is not treated as a value, it signifies the absence of one. If you want to delete those rows you have to say
DELETE FROM offers WHERE status <> 3 OR status IS NULL
null is not a string it is a keyword in mysql, so use:-
DELETE FROM offers WHERE STATUS is null

What is the Meaning of "DEFAULT" in Mysql Datetime?

In this following mysql command i am seeing the Keyword DEFAULT
CREATE Table User
(
id int(11) NOT NULL AUTO_INCREMENT,
created_at datetime DEFAULT NULL
)
My Question Is :
Why is there a default keyword if i am allowing datetime to be null
Is it about the Datetime syntax, so that it should be in default format.
please explain it to me. I also found the documentation page for DEFAULT in mysql. but i am not understanding it.
[N.B.: Pardon Me, If this a beginner question, or already asked. But I did not find exactly what i was looking for.]
1. Why is there a default keyword if i am allowing datetime to be null
If a column definition includes no explicit DEFAULT value, MySQL determines the default value as described in Section 12.7, “Data Type Default Values”.
MySQL will add default value to column definition by it's own rules if you don't set it manually. So, DEFAULT is always presented, except special datatypes
DEFAULT does not apply to the BLOB, TEXT, GEOMETRY, and JSON types
2. Is it about the Datetime syntax, so that it should be in default format.
No. If you allow null, then column can take any valid datetime value OR null. Null is valid too. And from manual:
If the column can take NULL as a value, the column is defined with an explicit DEFAULT NULL clause.
As result, if you create table with column created_at datetime it will be converted according these rules to created_at datetime DEFAULT NULL.
Update
Some examples. Next CREATE TABLE statements are equivalent:
CREATE Table User
(
created_at datetime NULL
);
CREATE Table User
(
created_at datetime DEFAULT NULL
);
You said, that you "allow null" for this column. Probably, you was using first query with created_at datetime NULL syntax. But MySQL really translates it into second query, because of rules above.
Why is there a default keyword if i am allowing datetime to be null
You mistake the NULL after DEFAULT with the NULL that allows a column to contain NULL values. Read below about the difference.
Is it about the Datetime syntax, so that it should be in default format.
The DEFAULT keyword in a CREATE TABLE statement doesn't tell anything about any format. It specifies the default value to be used for the column when an INSERT statement doesn't provide a value for it.
The complete definition of a table column in the CREATE TABLE statement contain the following pieces, in this order:
field name;
field type;
NULL or NOT NULL - are NULL values allowed to be stored in the field? If neither is specified, NULL is assumed;
DEFAULT default value - the value to be used for the field when an INSERT statement doesn't provide a value for it; NULL can be used as default value if the column is nullable; if it's not specified, MySQL uses some rules to compute the default value based on the field type;
AUTO_INCREMENT - when a value is not provided for the column, MySQL uses the biggest value existing in the column plus one; can be used only with integer and float columns;
one of UNIQUE, UNIQUE KEY, KEY, PRIMARY KEY - the first two are equivalent and they specify that the column is an unique index of the table (it cannot contain the same value for two or more rows); the last two specify the column is the identifier of the row (it is an UNIQUE INDEX and it cannot contain NULL values); these attributes can be specified here for compatibility with other database systems; on MySQL one usually specifies the table indexes after the columns using a different syntax;
COMMENT string - a comment for the column; it is not used by MySQL but it can be useful for the developers (to specify what represents the column);
other, less used, options.
Only the first two pieces from the list above (the name and the type) are required; all the others are optional. If present, they must be provided in the order of the list.
Your statement:
CREATE TABLE User
(
id INT(11) NOT NULL AUTO_INCREMENT,
created_at DATETIME DEFAULT NULL
)
The column id specifies NOT NULL, skips DEFAULT and specifies AUTO_INCREMENT. Without AUTO_INCREMENT, MySQL uses 0 as the default value (this is the default value for integer types). Because of AUTO_INCREMENT, when a value is not provided in the INSERT statement, MySQL finds the largest value already stored in the column, increases it with 1 and uses this computed value for the column.
The column created_at doesn't specify if it allows NULL values (it allows them, this is the default) and specifies that the default value for the column is NULL.
Examples
Let's see how it works:
INSERT INTO User(id, created_at) VALUES (5, '2016-06-01 11:22:33')
inserts a new row having the values provided in the INSERT statement; no surprise here.
INSERT INTO User(created_at) VALUES ('2016-06-02 12:34:56')
inserts a new row with id = 6, created_at = '2016-06-02 12:34:56'. Because a value was not provided for column id, the AUTO_INCREMENT option generated 6 for it (the successor of the larger value already in the column).
The same happens when NULL is provided for the AUTO_INCREMENT column:
INSERT INTO User(id, created_at) VALUES (NULL, '2016-06-03')
inserts id = 7, created_at = '2016-06-03 00:00:00'. Please also note that, because the time components were not specified in the value provided for created_at, MySQL defaulted them to 00:00:00.
A new statement:
INSERT INTO User(id) VALUES (10)
creates a row having id = 10, created_at = NULL.
The statement
INSERT INTO User() VALUES()
looks strange but it's perfectly legal and inserts a row that uses the default values for all its columns. In this case, the new row have the values id = 11, created_at = NULL.
Finally, the statement
INSERT INTO User(id) VALUES(5)
fails because there already exists a row having id = 5 in the table (it was inserted by the first statement at the start of the examples.
The DEFAULT constraint is used to insert a default value into a column.
The default value will be added to all new records, if no other value is specified.
The DEFAULT value clause in a data type specification indicates a default value for a column. With one exception, the default value must be a constant; it cannot be a function or an expression.
For More Information See This Question.
MySQL columns with default null - stylistic choice, or is it?
Think of NULL as unknown. This has interesting implications, like:
mysql> select null = true;
+-------------+
| null = true |
+-------------+
| NULL |
+-------------+
and
mysql> select null != true;
+--------------+
| null != true |
+--------------+
| NULL |
+--------------+
From MySQL Data Type Default Values
If the column can take NULL as a value, the column is defined with an explicit DEFAULT NULL clause.
For MySQL those definitions are all same and identical
column type
column type NULL
column type DEFAULT NULL
column type NULL DEFAULT NULL

Not null confusion

In phpMyAdmin, as we create table there is not null constraints by default for all fields...and as per my knowledge when we set the constraint to not null...it doesn't allow user to remain field empty which are not null as per this link.....
http://www.techopedia.com/definition/27370/not-null-constraint
now my question is..according to this link, not null means every row of data must contain a value - it cannot be left blank during insert or update operations.....but when i insert data programatically like insert into, i am able to insert data in just two fields and other remains blank although there is not null constraints on that fields ...and still not generates any error....so i don't understand how not null works???
for example, i create table with lets say 5 fields...
create table myTable
(
Column1 int not null,
Column2 int not null,
Column3 int not null,
Column4 int not null,
Column5 int not null,
)
and insert values in just two fields like
"INSERT INTO myTable (column1,column2) VALUES(10,20)";
but other fields i don't give any '' so it takes 0 as value....and still i am able to insert data with no error...how is that possible??
Everything that has the NOT NULL constraint set needs to contain data. If you insert data programmatically and you do not insert data for a NOT NULL cell, then you will get an SQL Error.
e.g. you have this table:
CREATE TABLE test (
id INTEGER PRIMARY_KEY AUTO_INCREMENT,
some_value INTEGER NOT NULL,
some_other_value INTEGER);
Then some_value will contain data in every data set returned, some_other_value may or may not contain data in every data set returned. The only thing to work around this would be this:
CREATE TABLE test (
id INTEGER PRIMARY_KEY AUTO_INCREMENT,
some_value INTEGER NOT NULL DEFAULT 0,
some_other_value INTEGER);
If you now set data programatically and do not set data for some_value, some_value will default to 0 (or to whatever data you set the default to on table creation).
Maybe you can refer to this link:
For multiple-row INSERT statements or INSERT INTO ... SELECT
statements, the column is set to the implicit default value for the
column data type. This is 0 for numeric types, the empty string ('')
for string types, and the “zero” value for date and time types. INSERT
INTO ... SELECT statements are handled the same way as multiple-row
inserts because the server does not examine the result set from the
SELECT to see whether it returns a single row. (For a single-row
INSERT, no warning occurs when NULL is inserted into a NOT NULL
column. Instead, the statement fails with an error.)
If a column definition includes no explicit DEFAULT value and it is defined as "Not Null" then Mysql will automatically assign default value to the column based on datatype. e.g. 0 for integer and "" for varchar
If you create a unique index on a column, the default value will be accepted with the first row but will give an error with subsequent inserts.

What is the default value for a field if no default value is provided?

I hope this isn't a dumb question. You can set a default value for all variables or a function for when it is inserted. but if the field is not required to insert and you don't allow null values, what is the "blank" value that you see in phpMyAdmin? in a query is it returned as empty string, etc?
just trying to figure it out, I want to query for all records such that the value for a specific column in that record is not "empty" or blank or whatever.
thanks.
Referring to the manual,
For data entry for a NOT NULL column that has no explicit DEFAULT
clause, if an INSERT or REPLACE statement includes no value for the
column, or an UPDATE statement sets the column to NULL, MySQL handles
the column according to the SQL mode in effect at the time:
If strict SQL mode is not enabled, MySQL sets the column to the implicit default value for the column data type.
If strict mode is enabled, an error occurs for transactional tables and the statement is rolled back. For nontransactional tables, an
error occurs, but if this happens for the second or subsequent row of
a multiple-row statement, the preceding rows will have been inserted.
So your question now may be, what are the implicit default values for the various column data types? Here you go:
Implicit defaults are defined as follows:
For numeric types, the default is 0, with the exception that for integer or floating-point types declared with the AUTO_INCREMENT
attribute, the default is the next value in the sequence.
For date and time types other than TIMESTAMP, the default is the appropriate “zero” value for the type. For the first TIMESTAMP column
in a table, the default value is the current date and time. See Section 10.3, “Date and Time Types”.
For string types other than ENUM, the default value is the empty string. For ENUM, the default is the first enumeration value.
There IS no default value unless you specify one (i.e. unless you define a "default constraint" for the column in question).
Here's an example for adding a default on an existing column:
ALTER TABLE dbo.customer ALTER COLUMN contactname SET DEFAULT 'Unknown'
Here's an example creating the table with a default:
CREATE TABLE Books (
ID SMALLINT NOT NULL,
Name VARCHAR(40) NOT NULL,
PubID SMALLINT NOT NULL DEFAULT 0
)
It's good practice to declare ALL columns "not null", and provide default constraints as appropriate.
In the "books" example above, if you "insert" without specifying PubID, the PubID will be zero.
In the same example, if you "insert" without specifying ID or Name ... you'll get an error.
If you want MySQL to auto-assign an ID, use this syntax instead:
CREATE TABLE Books (
ID SMALLINT NOT NULL AUTO_INCREMENT,
Name VARCHAR(40) NOT NULL,
PubID SMALLINT NOT NULL DEFAULT 0
)
If you want to disallow null :-
alter table YOUR_TABLE modify column COLUMN varchar(255) not null default '';
The above query will disallow null and assign an empty string when the value is not supplied.
In phpmysqladmin, blank = empty.
Via PHP mysqli function or mysql function, null value is returned as null still.
Once you have apply the query, you can easily filter that by using
select ... from YOUR_TABLE
where COLUMN != ""; <-- no need to check is null
<-- because the first query already enforce not null
However, is best for you do this before perform the alter :-
update YOUR_TABLE set COLUMN = ""
where COLUMN is null;