It actually doesn't accept NULL values it considers it as empty string. That's because you have your server in non-strict mode. That controls how MySQL handles invalid or missing values in inserts and updates. You can read more about modes here: http://dev.mysql.com/doc/refman/5.6/en/sql-mode.html#sql-mode-strict
mysql> insert into cities(state_id) values (20);
Query OK, 1 row affected, 1 warning (0.07 sec)
mysql> show warnings;
+---------+------+-------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------+
| Warning | 1364 | Field 'name' doesn't have a default value |
+---------+------+-------------------------------------------+
mysql> select name is null from cities where id = LAST_INSERT_ID();
+--------------+
| name is null |
+--------------+
| 0 |
+--------------+
1 row in set (0.00 sec)
mysql> SET sql_mode = 'STRICT_ALL_TABLES';
Query OK, 0 rows affected (0.00 sec)
mysql> insert into cities(state_id) values (20);
ERROR 1364 (HY000): Field 'name' doesn't have a default value
Answer from Károly Nagy on Stack ExchangeVideos
It actually doesn't accept NULL values it considers it as empty string. That's because you have your server in non-strict mode. That controls how MySQL handles invalid or missing values in inserts and updates. You can read more about modes here: http://dev.mysql.com/doc/refman/5.6/en/sql-mode.html#sql-mode-strict
mysql> insert into cities(state_id) values (20);
Query OK, 1 row affected, 1 warning (0.07 sec)
mysql> show warnings;
+---------+------+-------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------+
| Warning | 1364 | Field 'name' doesn't have a default value |
+---------+------+-------------------------------------------+
mysql> select name is null from cities where id = LAST_INSERT_ID();
+--------------+
| name is null |
+--------------+
| 0 |
+--------------+
1 row in set (0.00 sec)
mysql> SET sql_mode = 'STRICT_ALL_TABLES';
Query OK, 0 rows affected (0.00 sec)
mysql> insert into cities(state_id) values (20);
ERROR 1364 (HY000): Field 'name' doesn't have a default value
To Károly Nagy's point,
You can use
SET SQL_MODE = 'STRICT_ALL_TABLES';
I'm sure you may already know but that is equivilent to:
SET @@SESSION.SQL_MODE = 'STRICT_ALL_TABLES';
Which, must be set for every session. And you can checky this by running this after the above statement.
SELECT @@SESSION.SQL_MODE; -- 'STRICT_ALL_TABLES'
SELECT @@GLOBAL.SQL_MODE; -- 'NO_ENGINE_SUBSTITUTION'
If you have access please set this at the global level:
SET @@GLOBAL.SQL_MODE = 'STRICT_ALL_TABLES';
Which becomes the default for every new session thereafter.
Cheers, Jay ;-]
NOTE: Tested On MySQL Version 5.6.23-log & MySQL Workbench 6.2.5
You should use IS NOT NULL. (The comparison operators = and <> both give UNKNOWN with NULL on either side of the expression.)
SELECT *
FROM table
WHERE YourColumn IS NOT NULL;
Just for completeness I'll mention that in MySQL you can also negate the null safe equality operator but this is not standard SQL.
SELECT *
FROM table
WHERE NOT (YourColumn <=> NULL);
Edited to reflect comments. It sounds like your table may not be in first normal form in which case changing the structure may make your task easier. A couple of other ways of doing it though...
SELECT val1 AS val
FROM your_table
WHERE val1 IS NOT NULL
UNION ALL
SELECT val2
FROM your_table
WHERE val2 IS NOT NULL
/*And so on for all your columns*/
The disadvantage of the above is that it scans the table multiple times once for each column. That may possibly be avoided by the below but I haven't tested this in MySQL.
SELECT CASE idx
WHEN 1 THEN val1
WHEN 2 THEN val2
END AS val
FROM your_table
/*CROSS JOIN*/
JOIN (SELECT 1 AS idx
UNION ALL
SELECT 2) t
HAVING val IS NOT NULL /*Can reference alias in Having in MySQL*/
You can filter out rows that contain a NULL value in a specific column:
SELECT col1, col2, ..., coln
FROM yourtable
WHERE somecolumn IS NOT NULL
If you want to filter out rows that contain a null in any column then try this:
SELECT col1, col2, ..., coln
FROM yourtable
WHERE col1 IS NOT NULL
AND col2 IS NOT NULL
-- ...
AND coln IS NOT NULL
Update: Based on your comments, perhaps you want this?
SELECT * FROM
(
SELECT col1 AS col FROM yourtable
UNION
SELECT col2 AS col FROM yourtable
UNION
-- ...
UNION
SELECT coln AS col FROM yourtable
) T1
WHERE col IS NOT NULL
And I agre with Martin that if you need to do this then you should probably change your database design.
Just use an ALTER TABLE... MODIFY... query and add NOT NULL into your existing column definition. For example:
ALTER TABLE Person MODIFY P_Id INT(11) NOT NULL;
A word of caution: you need to specify the full column definition again when using a MODIFY query. If your column has, for example, a DEFAULT value, or a column comment, you need to specify it in the MODIFY statement along with the data type and the NOT NULL, or it will be lost. The safest practice to guard against such mishaps is to copy the column definition from the output of a SHOW CREATE TABLE YourTable query, modify it to include the NOT NULL constraint, and paste it into your ALTER TABLE... MODIFY... query.
Try this, you will know the difference between change and modify,
ALTER TABLE table_name CHANGE curr_column_name new_column_name new_column_datatype [constraints]
ALTER TABLE table_name MODIFY column_name new_column_datatype [constraints]
- You can change name and datatype of the particular column using
CHANGE. - You can modify the particular column datatype using
MODIFY. You cannot change the name of the column using this statement.
Hope, I explained well in detail.
NULL means you do not have to provide a value for the field...
NOT NULL means you must provide a value for the fields.
For example, if you are building a table of registered users for a system, you might want to make sure the user-id is always populated with a value (i.e. NOT NULL), but the optional spouses name field, can be left empty (NULL)
I would suggest
- Use NOT NULL on every field if you can
- Use NULL if there is a sensible reason it can be null
Having fields which don't have a meaningful meaning for NULL nullable is likely to introduce bugs, when nulls enter them by accident. Using NOT NULL prevents this.
The commonest reason for NULL fields is that you have a foreign key field which is options, i.e. not always linked, for a "zero or one" relationship.
If you find you have a table with lots of columns many of which can be NULL, that starts sounding like an antipattern, consider whether vertical partitioning makes more sense in your application context :)
There is another useful use for NULL - making all the columns in an index NULL will stop an index record being created for that row, which optimises indexes; you may want to index only a very small subset of rows (e.g. for an "active" flag set on only 1% or something) - making an index which starts with a column which is usually NULL saves space and optimises that index.
From the MySQL documentation (emphasis mine):
Declare columns to be NOT NULL if possible. It makes SQL operations faster, by enabling better use of indexes and eliminating overhead for testing whether each value is NULL. You also save some storage space, one bit per column. If you really need NULL values in your tables, use them. Just avoid the default setting that allows NULL values in every column.
So, on the contrary, NOT NULL saves disk space, rather than costing more.
Which Engine are you using?
At most, NULLs take 1 byte per 8 nullable columns. In the other direction, a NULL value may occupy less space. What datatype are you talking about?
See also SET. This datatype allows you to put up to 64 boolean flags in up to 8 bytes of space.
Long ago, I decided that the space considerations of NULL versus NOT NULL were so insignificant as to be not worth the time to think about it. I have a Rule of Thumb: If a tentative optimization (NULL, etc) is not going to save 10% of something (space, speed, etc), then drop the topic and look for something else to optimize.
Instead, I focus on using NOT NULL except when I have a business reason or a processing logic that can make good use of NULL:
- Not yet set (eg, date of death)
- Optional (eg, middle initial)
- Not available (eg, middle initial)
- etc.
I do insist on thinking carefully about datatypes when initially creating a table. It is painful to make schema changes later. Examples:
- Will this fit into a 2-byte
SMALLINTinstead of a 4-byteINT. (Smaller saves disk space and helps speed) - Virtually all ints can/should be
UNSIGNED. - Get the
CHARACTER SETandCOLLATIONcorrect. NULLvsNOT NULL. (For logic reasons, not speed or space)- etc.