Why won't if clause return nationality - mysql

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 = ''

Related

Check for all null values in a GROUP BY [duplicate]

This question already has answers here:
MySQL AVG() return 0 if NULL
(3 answers)
Closed last month.
I have the following structre
id val
1 ...
.
.
2 ...
.
.
3 null
3 null
3 null
4 ...
.
.
Basically each id has multiple no. of values. And an id has either all values as integers or all values as null
What I want is to perform an aggregate (like AVG) on val group by id. If that id has null values, I want to put 5 there.
#1
SELECT id, (CASE SUM(val) WHEN null THEN 5 ELSE AVG(val) END) AS ac FROM tt GROUP BY id
> executes ELSE even for id = 3
In CASE, there should be an aggregate function that when done on null values give null.
I checked SUM and MAX like
SELECT SUM(val) FROM tt WHERE id = 3
> null
and it gives null here but doesn't work in main statement. I guess it is related to the type of equality and hence tried WHEN IS NULL but its a syntax error.
Also, is there some more standard way of indicating group of values as all null rather than using SUM or MAX.
You can use if condition :
select id, If(sum(val) is null, 5, AVG(val)) as average
FROM tt
group by id
check here : https://dbfiddle.uk/Uso9nNTM
The exact problem with your CASE expression is that to check for null in MySQL we have to use IS NULL rather than equality. So use this version:
CASE WHEN SUM(val) IS NULL THEN 5 ELSE AVG(val) END
But we might as well just use COALESCE() to assign an average of 5 for those id groups having all null values.
SELECT id, COALESCE(AVG(val), 5) AS avg_val
FROM tt
GROUP BY id;
Note that the AVG() function by default ignores nulls. Therefore, the expression AVG(val) would only be null if every record in an id group were having null for val.

SELECT row if certain field is NOT null. Else, select row with null field instead

I'm having a hard time solving my sql problem. Would like to select a row if a certain field(LOOKUP) is not null. Else, get the row with the null field instead. Please see table below:
(PAYCODE must be unique)
PAYCODE
LOOKUP
ACCOUNT
201
null
720001
201
659057
999999
202
null
720002
The output must be:
PAYCODE
LOOKUP
ACCOUNT
201
659057
999999
202
null
720002
This looks so easy but I am new to sql and solving this for 2 days while searching for solutions but no luck.
You could try the following logic:
SELECT *
FROM yourTable t1
WHERE LOOKUP IS NOT NULL OR
NOT EXISTS (SELECT 1 FROM yourTable t2
WHERE t2.PAYCODE = t1.PAYCODE AND
t2.LOOKUP IS NOT NULL);
Demo
This logic retains any record whose LOOKUP is not null or any record for which there is no non null record having the same PAYCODE.

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;

Keep null values as '' after creating new table?

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

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.