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;
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
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.
I have been tearing my hair out over this issue. I am working with an existing data set and need to remove all the null values from the columns in table A and shunt them across so they are ordered like in table B
I need something which is equivalent to Coalesce but to retrieve the nth value so I can get the result sorted like in table B
What I have:
Table A
Name CURRENT OCT12 SEPT12 AUG12 JUL12 JUN12 MAY12 APR12
---------------------------------------------------------
A NULL NULL Aug-12 NULL NULL Jun-12 NULL Apr-12
B Nov-12 NULL Aug-12 NULL Jul-12Jun-12 NULL Apr-12
What I need:
Table B
Name Change1 Change2 Change3 Change4 Change5 Change6
----------------------------------------------------
A Aug-12 Jun-12 Apr-12 NULL NULL NULL
B Nov-12 Aug-12 Jul-12 Jun-12 Apr-12 NULL
Code-wise, it would be something like:
Select
first non-null value as Change1
,second non-null value as Change2
,third non-null value as Change3
,fourth non-null value as Change4
,fifth non-null value as Change5...etc..
from Table_A
I am using MySQL and i have no idea how to reference the nth non null value in order to call them into Table_B
Does anyone have any ideas?
I am not sure if I would reccommend using this solution... normalization of your data is always a better choice, but I wanted to answer using plain SQL with some strings functions. This query should return what you are looking for:
SELECT
Name,
Changes,
REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(Changes, ',', 1)), ',', 1)) as Change1,
REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(Changes, ',', 2)), ',', 1)) as Change2,
REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(Changes, ',', 3)), ',', 1)) as Change3,
REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(Changes, ',', 4)), ',', 1)) as Change4,
REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(Changes, ',', 5)), ',', 1)) as Change5,
REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(Changes, ',', 6)), ',', 1)) as Change6
FROM (
SELECT
Name,
CONCAT_WS(',', CURRENT, OCT12, SEPT12, AUG12, JUL12, JUN12, MAY12, APR12, ',') as Changes
FROM
TableA
) s
I'm concatenating all values in a comma separated string, with two commas at the end of the string (one comma would be enough anyway, but it's easier to put two and just ignore the last one...), and since I'm using CONCAT_WS it will automatically skip null values, and the resulting string will be something like Aug-12,Jun-12,Apr-12,,.
Then in the outer query I'm extracting the n-th element of the string, using SUBSTRIG_INDEX. I would recommend to normalize your database, but if you need a quick fix this solution might be a good starting point.
See it working here.
Please notice that I am not returning NULL values where there are no changes, but I am returning empty strings instead. This can be changed if you need.
If you don't want to use strings functions you can try this sql using unpivot and row number partitioning:
CREATE TABLE #TableA
(
"Name" VARCHAR(10),
"CURRENT" VARCHAR(10),
OCT12 VARCHAR(10),
SEPT12 VARCHAR(10),
AUG12 VARCHAR(10),
JUL12 VARCHAR(10),
JUN12 VARCHAR(10),
MAY12 VARCHAR(10),
APR12 VARCHAR(10)
)
INSERT INTO #TableA
("Name", "CURRENT", OCT12, SEPT12, AUG12, JUL12, JUN12, MAY12, APR12)
VALUES
('A', NULL, NULL, 'Aug-12', NULL, NULL, 'Jun-12', NULL, 'Apr-12'),
('B', 'Nov-12', NULL, 'Aug-12', NULL, 'Jul-12', 'Jun-12', NULL, 'Apr-12')
SELECT * FROM #TableA;
Select "Name",
Min(Case row_num When 1 Then data End) Change1,
Min(Case row_num When 2 Then data End) Change2,
Min(Case row_num When 3 Then data End) Change3,
Min(Case row_num When 4 Then data End) Change4,
Min(Case row_num When 5 Then data End) Change5,
Min(Case row_num When 6 Then data End) Change6
From
(
select "Name",data,DBColumnName,
ROW_NUMBER() OVER (PARTITION BY "Name" ORDER BY "Name") row_num
From #TableA
unpivot (data for DBColumnName in ("CURRENT",OCT12,SEPT12,AUG12,JUL12,JUN12,MAY12,APR12) ) as z
) TableB
group by "Name";
References:
-- TSQL Pivot without aggregate function
-- https://www.sqlservertutorial.net/sql-server-window-functions/sql-server-row_number-function/
-- https://learn.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-ver15
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 = ''