Keep null values as '' after creating new table? - mysql

I have the following table:
cats
----------------------------------
name owner no_of_kittens
----------------------------------
bob hanna 1
tip frank
spark george 6
lucky rita
lady terry 3
----------------------------------
I want to create a new table the following way:
CREATE TABLE cats_with_kittens (
name VARCHAR(255) NOT NULL,
no_of_kittens VARCHAR(255)
);
INSERT INTO cats_with_kittens
SELECT name, count(no_of_kittens)
FROM cats
GROUP BY name;
The problem is that in the resulting table, the no_of_kittens values of tip and lucky is 1 instead of empty string as in the initial table.
Is there a way to create the table so that values with no no_of_kittens is empty string ''?

COUNT() will also count empty string, you can add case express to make it non-countable :
SELECT name, COUNT(CASE WHEN no_of_kittens <> '' THEN 1 ELSE 0 END) AS no_of_kittens
FROM cats
GROUP BY name;

INSERT INTO cats_with_kittens
SELECT name, case when count(no_of_kittens) = 0 then ''
else count(no_of_kittens)
end
FROM cats
GROUP BY name;
Here is a small demo

Related

Showing all column names where value is null

is there anyway i can show all column names where values are null?
For example i have table like this:
id
name
surname
1
Jack
NULL
2
NULL
Grain
3
NULL
NULL
And i want my result to look like that:
id
nullFields
1
name
2
surname
3
name, surname
Perfect solution would be some sql which takes all the columns and check them (if there wouldnt be need to manually input column name) but if there is no such possibility "normal solution" will do fine.
We can use the base string functions here:
SELECT id, CONCAT_WS(', ',
CASE WHEN name IS NULL THEN 'name' END,
CASE WHEN surname IS NULL THEN 'surname' END) AS nullFields
FROM yourTable
ORDER BY id;

Can the database table be ordered such that NULL values appear at the bottom?

I have a database table called 'Customers' like this:
Sl Name Profession
1 ABC Doctor
2 QWE Engineer
3 ERT null
4 DEF Doctor
5 JGJ null
I want to order this table as all the names with professions are at the beginning and names without profession(null) at the bottom, like this:
Sl Name Profession
1 ABC Doctor
2 QWE Engineer
4 DEF Doctor
5 JGJ null
3 ERT null
Is there any query to do this? Thanks in advance..
NULLs in MySQL (and most flavors of SQL) sort first by default, not last. One general way to force NULL values to the bottom is to use a CASE or IF expression:
SELECT
Sl, Name, Profession
FROM yourTable
ORDER BY
IF(Profession IS NOT NULL, 0, 1),
Sl;
use order by
select * from table_name
order by case when Profession is not null then 1 else 2 end
NO DB engine provide you order rows without using order by

INSERT id from other column or NULL if value does not exist

THE DATA
I have a set of data in the following format:
CAR_MAKE TABLE
ID MAKE
1 Ford
2 Tesla
3 Acura
4 Honda
5 Toyota
MAKE_NOTES TABLE
NOTE_ID MAKE_ID MAKE_NAME NOTE
1 1 Ford New QNX-Based Sync System
2 2 Tesla Looking forward to Model 3
3 5 Toyota Updated Corolla 2018
4 Null Ferrari Very Fast and Very Red
I know there's repeating data (make_name) between table 1 and table 2. Let's assume I can't mess with the data. I also can't guarantee that an entry would have been made in car_make first. In such a case make_notes.make_id should be null.
WHAT I'VE DONE SO FAR
What I'm trying to do is INSERT a row into make_notes, inserting null into make_id if it does not exist in car_make, otherwise inserting car_make.id.
This works fine if, make_name exists in car_make... but if I attempt to insert a record with a make_name that does not exist in car_make, no record is inserted (no error is thrown either).
INSERT INTO make_notes (
make_id,
make_name,
note
)
SELECT
id,
'ford',
'New Note'
FROM car_make
WHERE make = 'ford';
I've also tried to use this as a subquery:
SELECT
CASE
WHEN (SELECT EXISTS (SELECT 1 FROM car_make where make = 'Ferrari') = 1)
THEN car_make.id
ELSE null
END AS make_id
FROM car_make;
I have not been albe intergrate it into my main query without throwing an error. As a stand alone query it returns one row for each entry in car_make, as null if 'Ferrari' does not exist, and each id if it does.
QUESTION
How do I create an insert query that will insert into 'make_notes', and insert 'null' if make_name does not exist in car_make, and insert car_make.id if make_name does exist?
I think using an IF() clause should work for your case:
INSERT INTO `make_notes` (
make_id,
make_name,
note
)
VALUES(
IF(
((SELECT COUNT(*) FROM `car_make` WHERE `make` = 'ford') > 0),
(SELECT `id` FROM `car_make` WHERE `make` = 'ford'),
NULL
),
'ford',
'New note'
);
I don't think you can do that with one query. I think you have to run a select to get the ID from the car_make table. Then you do the insert.

Select columns that are not null in any record

I need to analyze a MySQL table and want to determine all columns that never contain NULL, 0 or an empty string in any record in that table.
I do not have a clue how to do that, since MySQL expects me to select the columns at the beginning of the statement. I thought I could maybe rotate the table by 90° and then do something like
SELECT column_header FROM rotated_table WHERE record_1 <> NULL AND record_2 <> NULL AND [...]
But this seems to be a lot of work.
Is there an easier way to get the information i require?
Update example:
Table1:
name street zip
MyName 1st Ave. 1000
OtherName 2nd Street NULL
My statement now should show something like:
name street
MyName 1st Ave.
OtherName 2nd Street
Because the column zip contains a NULL value.
If there was an additional row like
name street zip
MyName 1st Ave. 1000
OtherName 2nd Street NULL
NULL Foo blvd. 3453
It should return
street
1st Ave.
2nd Street
Foo blvd.
Because name and zip contain at least one NULL value.
You can use the behavior of COUNT ignoring NULL values to your advantage.
Subtract the count of the column you're examining from the count of the number of rows. Any column that returns a value of 0 does not contain a NULL value. You'll need to use a CASE statement to convert any values you consider to be "empty" into NULL.
This approach also eliminates the need copying the entire table in order to "rotate" it.
I whipped up an example here in SQLFiddle which should work for you.
Here's the content of my SQLFiddle example in case the link becomes unusable:
CREATE TABLE address
(
address int auto_increment primary key,
street1 varchar(20),
street2 varchar(20),
city varchar(20),
state varchar(20),
zip int,
comment varchar(20)
);
INSERT INTO address
(street1, street2, city, state, zip, comment)
VALUES
('123 Main St.', null, 'Cleveland', 'OH', 44123, ''),
('1313 Mockingbird Ln.', null, 'Cleveland', 'OH', 0, 'Unknown zip'),
('321 Main St.', 'Apt #1', 'Cleveland', 'OH', 44123, ''),
('321 Main St.', 'Apt #2', 'Cleveland', 'OH', 44123, '');
SELECT
COUNT(*) rows, -- not really needed, you can remove this
COUNT(*) - COUNT(CASE ad.street1 WHEN '' THEN NULL ELSE ad.street1 END) empty_street1,
COUNT(*) - COUNT(CASE ad.street2 WHEN '' THEN NULL ELSE ad.street2 END) empty_street2,
COUNT(*) - COUNT(CASE ad.city WHEN '' THEN NULL ELSE ad.city END) empty_city,
COUNT(*) - COUNT(CASE ad.state WHEN '' THEN NULL ELSE ad.state END) empty_state,
-- Change the value being compared based on the column type. Strings '', numbers 0, etc.
COUNT(*) - COUNT(CASE ad.zip WHEN 0 THEN NULL ELSE ad.zip END) empty_zip,
COUNT(*) - COUNT(CASE ad.comment WHEN '' THEN NULL ELSE ad.comment END) empty_comment
FROM address ad;
Which results in:
ROWS EMPTY_STREET1 EMPTY_STREET2 EMPTY_CITY EMPTY_STATE EMPTY_ZIP EMPTY_COMMENT
4 0 2 0 0 1 3
The correct comparison to NULL is IS NULL or IS NOT NULL. So:
SELECT column_header
FROM rotated_table
WHERE record_1 IS NOT NULL AND record_2 IS NOT NULL AND [...];
However "record" is an odd name for columns. You want to be sure the column names are in the WHERE clause.

Why won't if clause return nationality

In the following SQL select statement, I want nationality to print if name is null, and I have a SQL clause's if syntax working, but am not seeing nationality print out in the following:
table test2
id integer
case integer
nationality char(10)
name char(24)
1 1 france ""
2 2 england john
select t.id,
if(t.name is null, t.nationality, t.name)
as name_equivalent
from test2 t;
produces
id name_equivalent
1 ""
2 john
Why is that?
Thank You.
null is not equivalent to the empty string. The empty string '' is a valid form of data, null indicates there is no data present.
Try either
if (t.name is null or t.name='', t.nationality, t.name)
Or set the name in the first column to null
1 1 france null
You're checking if the name is null, but it was set to an empty string. To check for both, you need:
if(t.name is null or t.name='', t.nationality, t.name)
It looks like France's name field is actually an empty string, and not null. You need to also account for it being empty in your select statement. Such as t.name = ''