I have a mysql table with a null-able int column named 'status', and I have two records in the table where one of the status is 2 when the other is NULL, but when I select the records with query 'status!=2', the record (status=null) is not shown.
mysql>
mysql>
mysql> desc admin_user;
+-------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| acct_name | varchar(32) | YES | | NULL | |
| password | varchar(32) | YES | | NULL | |
| user_name | varchar(32) | YES | | NULL | |
| description | varchar(128) | YES | | NULL | |
| status | int(11) | YES | | NULL | |
| role | int(11) | NO | | 1 | |
| create_date | date | YES | | NULL | |
| update_date | date | YES | | NULL | |
+-------------+------------------+------+-----+---------+----------------+
9 rows in set (0.00 sec)
mysql> select id, acct_name, status from admin_user;
+----+-----------+--------+
| id | acct_name | status |
+----+-----------+--------+
| 1 | letme | NULL |
| 3 | admin | 2 |
+----+-----------+--------+
2 rows in set (0.00 sec)
mysql> select id, acct_name, status from admin_user where status=2;
+----+-----------+--------+
| id | acct_name | status |
+----+-----------+--------+
| 3 | admin | 2 |
+----+-----------+--------+
1 row in set (0.00 sec)
mysql> select id, acct_name, status from admin_user where status IS NULL;
+----+-----------+--------+
| id | acct_name | status |
+----+-----------+--------+
| 1 | letme | NULL |
+----+-----------+--------+
1 row in set (0.00 sec)
mysql> select id, acct_name, status from admin_user where status!=2;
Empty set (0.00 sec)
mysql>
As you can see, the record whose status is NULL can not be selected using the query 'status!=2'. I also tried 'status<>2'. Can anybody help?
Nulls are really interesting.
The NULL value can be surprising until you get used to it.
Conceptually, NULL means “a missing unknown value” and it is treated
somewhat differently from other values.
What's more
You cannot use arithmetic comparison operators such as =, <, or <> to
test for NULL
There are lots of different ways to write this. One of them being:
select id, acct_name, status from admin_user where status IS NULL
OR status != 2
Alterantively as #shA.t suggested.
select id, acct_name, status from table1 where COALESCE(status, 0) != 2
Just check that 0 is indeed a number that doesn't appear any where else in the table.
Related
In the database 'college2' there are 3 TABLES:'student, course & enrolment', and one(1) VIEW:'enrolment_status', which is created using the following command:
CREATE VIEW enrolment_status AS
SELECT code, COUNT(id)
FROM enrolment
GROUP BY code;
Explain command for 'course,enrolment and enrolment_status' results in:
mysql> EXPLAIN course;
+---------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| code | char(8) | NO | PRI | NULL | |
| name | varchar(90) | YES | MUL | NULL | |
| max_enrolment | char(2) | YES | | NULL | |
+---------------+-------------+------+-----+---------+-------+
3 rows in set (0.09 sec)
mysql> explain enrolment;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | char(6) | YES | MUL | NULL | |
| code | char(8) | YES | MUL | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.02 sec)
mysql> explain enrolment_status;
+-----------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------+------+-----+---------+-------+
| code | char(8) | YES | | NULL | |
| COUNT(id) | bigint(21) | NO | | 0 | |
+-----------+------------+------+-----+---------+-------+
2 rows in set (0.18 sec)
'max_enrolment' column in 'course' TABLE is the maximum allowed # of student for each course, say 10 or 20.
'count(id)' column in 'enrolment_status' VIEW (not table) is actual # of students enrolled in each course.
'id' column in 'enrolment' TABLE is the student id enrolled in a course.
HERE'S MY QUESTION:
I want to have the '# of seats left' which is the difference between 'max_enrolment' column and 'count(id)' column.
'#of seats left' can be a stand alone table or view or a column added to any of the above tables. How can i do this:
I tried many commands including the following,
CREATE VIEW seats_left AS (
SELECT course.code, course.max_enrolment - enrolment_status.count
FROM course, enrolment_status
WHERE course.code = enrolment_status.code);
...which gives me the following error message:
ERROR 1054 (42S22): Unknown column 'enrolment_status.count' in 'field list'
mysql> SELECT*FROM enrolment_status;
+----------+-----------+
| code | COUNT(id) |
+----------+-----------+
| COMP9583 | 7 |
| COMP9585 | 9 |
| COMP9586 | 7 |
| COMP9653 | 7 |
| COMP9654 | 7 |
| COMP9655 | 8 |
| COMP9658 | 7 |
+----------+-----------+
7 rows in set (0.00 sec)
mysql> SELECT code, max_enrolment FROM course;
+----------+---------------+
| code | max_enrolment |
+----------+---------------+
| COMP9583 | 10 |
| COMP9585 | 15 |
| COMP9586 | 15 |
| COMP9653 | 12 |
| COMP9654 | 10 |
| COMP9655 | 12 |
| COMP9658 | 12 |
+----------+---------------+
7 rows in set (0.00 sec)
+----------+---------------------+
| code | max_enrolment - cnt |
+----------+---------------------+
| COMP9583 | 9 |
| COMP9585 | 14 |
| COMP9586 | 14 |
| COMP9653 | 11 |
| COMP9654 | 9 |
| COMP9655 | 11 |
| COMP9658 | 11 |
+----------+---------------------+
7 rows in set (0.09 sec)
Try to use an acronym for in the view.
CREATE VIEW enrolment_status AS
SELECT code, COUNT(id) count
FROM enrolment
GROUP BY code;
Then you should be able to do this:
CREATE VIEW seats_left AS (
SELECT course.code, course.max_enrolment - enrolment_status.count
FROM course, enrolment_status
WHERE course.code = enrolment_status.code);
If you cannot change the view, then you must use the exact same name in the query:
CREATE VIEW seats_left AS (
SELECT course.code, course.max_enrolment - enrolment_status.'count(id)'
FROM course, enrolment_status
WHERE course.code = enrolment_status.code);
Try this:
SELECT b.`code`,max_enrolment - cnt from
(select `code`, cnt from
(select count(1) as cnt,`code` from enrolment_status
GROUP BY `code`) as a) as a
LEFT JOIN
(SELECT code,max_enrolment from course) as b
on a.`code` = b.`code`
You can change left join to right join
I ran the following in my sql database:
update table1 SET car_color_code="red metalic" where car_model="335i";
and it said:
Query OK, 1 row affected (0.06 sec) Rows matched: 1 Changed: 1
Warnings: 0
However, I dont see the change in the table
The table looks like this:
------------------------------------------------
| ID | model | manufacturer | car_color_code |
| 1 | 335i | BMW | NULL |
------------------------------------------------
So the null from before should be replaced with "red metalic" but it stays NULL.
However when i try to insert again it says:
Rows matched: 1 Changed: 0 Warnings: 0
And when i try to select again I still dont see the change in car_color_code column...
My table description is
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| model | varchar(255) | NO | | NULL | |
| manufacturer | varchar(255) | NO | | NULL | |
| car_color_code | varchar(255) | NO | | NULL | |
+------------------+--------------+------+-----+---------+----------------+
You might have forgot to commit. It is possible that you have exited out of MySQL server and tried the select statement after relogging in.
Make sure you commit after you update.
I was trying to update a column value that has a null value.
Table:
+------------+-----------+-------+
| product_no | name | price |
+------------+-----------+-------+
| 1 | Cheese | 9.99 |
| NULL | Meat | 17.00 |
| 2 | Pepperoni | NULL |
+------------+-----------+-------+
Update:
UPDATE products SET product_no = 6 WHERE product_no = NULL;
Output:
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0 Changed: 0 Warnings: 0
Table definition:
+------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| product_no | int(11) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
| price | decimal(10,2) | YES | | NULL | |
+------------+---------------+------+-----+---------+-------+
Why is this not updating to 6?
Try this:
UPDATE products SET product_no = 6 WHERE product_no is NULL;
NULL value is special, use:
WHERE product_no IS NULL
or
WHERE product_no <=> NULL
The reason is because NULL is special.
MySql states:
To test for NULL, use the IS NULL and IS NOT NULL operators...
You cannot use arithmetic comparison operators such as =, <, or <> to test for NULL.
Hence:
UPDATE products SET product_no = 6 WHERE product_no IS NULL;
I have inherited a MySQL database, that has a table as follows:
mysql> describe stock_groups;
+--------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| group | varchar(5) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
| parent | varchar(5) | YES | | NULL | |
| order | int(11) | YES | | NULL | |
+--------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
When I run mysql> select * from stock_groups wheregroup='D2';
I get:
mysql> select * from stock_groups where `group`='D2';
+----+-------+------+--------+-------+
| id | group | name | parent | order |
+----+-------+------+--------+-------+
| 79 | D2 | MENS | D | 51 |
+----+-------+------+--------+-------+
1 row in set (0.00 sec)
and also i have a table:
mysql> describe stock_groups_styles_map;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| group | varchar(5) | NO | | NULL | |
| style | varchar(25) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
when I run:
mysql> select `group` from stock_groups_styles_map where style='N26';
+-------+
| group |
+-------+
| B1 |
| B11 |
| D2 |
| V2 |
+-------+
4 rows in set (0.00 sec)
how do i get the stock_groups.name ?
Join the tables, and select only the data you need. If you need unique rows, use the distinct keyword:
select -- If you need unique names, use "select distinct" instead of "select"
sg.name
from
stock_groups_styles_map as sgs
inner join stock_groups as sg on sgs.group = sg.group
where
sgs.style = 'N26'
You could also solve this using subqueries, but that would be rather inneficient in this case.
Something important
You should add the appropriate indexes to your tables. It will improve the performance of your database.
You can use inner join on group column
SELECT ss.group, sg.name from
stock_groups sg inner join stock_groups_styles_map ss on ss.group = sg.group
where ss.style='N26'
SELECT stock_groups.name FROM stock_groups_styles_map, stock_groups WHERE stock_groups_styles_map.style ='N26';
worked for me.
Given this table :
mysql> describe activity;
+---------------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------+-------------+------+-----+---------+-------+
| user_id | varchar(16) | NO | | NULL | |
| login_time | int(11) | NO | | NULL | |
| last_activity_time | int(11) | NO | | NULL | |
| last_activity_description | text | YES | | NULL | |
| logout_time | int(11) | NO | | NULL | |
+---------------------------+-------------+------+-----+---------+-------+
5 rows in set (0.01 sec)
I want to select the most recent last_activity_time (standard Unix timestamp) for each user who is logged in (i.e has one or more rows where logout_time is not zer0).
I tried
SELECT user_id, login_time, MAX(last_activity_time)
FROM activity
WHERE logout_time="0";
...but that found only a single entry with two users logged in, probably because I am selecting for MAX(last_activity_time)
What I want is something like
SELECT all unique user_ids
SELECT each of those which has one or more entries where `logout_time` != 0
SELECT the maximum value of `logout_time` for each of those
all in one single SELECT statement. How can I do that?
SELECT user_id, MAX(logout_time)
FROM activity
WHERE logout_time <> "0"
GROUP BY user_id;