SQLITE: Select another column if the first one is null - sqlite

I want to select the value from another column if there are no records in the first column (is null).
I want something like this:
SELECT (if Column1 IS NULL THEN Column2), Column3, Column4 FROM MyTable
How can I do that in SQLite?

Use the COALESCE function, which returns the first non-null argument:
SELECT COALESCE(Column1, Column2), Column3, Column4
FROM MyTable
In this case, you will get Column1 but if it is NULL, Column2 will be returned instead.

From Safari Books
Name
coalesce() — Return first non-NULL argument
Common Usage
coalesce( param1, param2, ... )
Description
The coalesce() function takes two or more parameters and returns the first non-NULL parameter. If all of the parameter values are NULL, a NULL is returned.
See Also
ifnull(), nullif()

You can use IFNULL function , try this
SELECT IFNULL(Column1, Column2), Column3, Column4 FROM MyTable

Use COALESCE(column1,column2) .
SELECT COALESCE(Column1, Column2), Column3, Column4 FROM MyTable

Related

check for null values in all columns of a table using SQLite

I have a table with more than 15 columns. 2 of of them are of the type varchar, and most of them of type int and float.
I am new to SQL and am trying to figure out a way by which I can check if any of the columns have a NULL value in it.
Had there been just 4 or 5 columns I could have checked them individually with
SELECT COUNT(*) FROM table_name WHERE col1 IS NULL OR col2 IS NULL OR col3 IS NULL ...
But is there any efficient way to do this on a lot of columns in SQLite specifically?
I have referred to other questions regarding this here but I cannot use xml or store anything. Also I am using SQLite and can only run a query.
There is no way (that I know of) to check all columns if they contain null without explicitly listing all the column names.
Your query is the proper way to do it.
If you want to shorten (not significantly) the code you could use these alternatives:
SELECT COUNT(*) FROM table_name WHERE col1 + col2 + col3 IS NULL;
or:
SELECT COUNT(*) FROM table_name WHERE col1 || col2 || col3 IS NULL;
or:
SELECT COUNT(*) FROM table_name WHERE MAX(col1, col2, col3) IS NULL;
The above queries work, for any data type of the columns, because if there is even only 1 column equal to null then addition, concatenation and the scalar function MAX() (and MIN()) all return null.
See the demo.

SQLite select where all columns are not null

I have column1, column2, column3, column4, column5 and so on.
If I know that one column is not null, I can use this query:
SELECT *
FROM table
WHERE columnA IS NOT NULL;
But now I want to select rows where all the columns are not null.
How to write is query easily?
Use the query look like this
SELECT *
FROM table_name
WHERE NOT column1 IS NULL AND NOT column2 IS NULL...

I need to create an Oracle query listing my table names followed by column names

Do you know how to create an Oracle query that will list my table name, followed by all the column names in that table? I have 5 tables in total.
Something like:
Table
Column1
Column2
Column3
Table2
Column1
Table3
Column1
Column2
I'm hard-pressed to imagine why you would want a single-column result that doesn't do anything to differentiate between what is a column name and what is a table name. You can do something like
select pseudo_column_name
from (
select table_name, table_name pseudo_column_name, 0 column_id
from user_tables
union all
select table_name, column_name, column_id
from user_tab_columns
)
order by table_name, column_id

How to delete multiple rows with 2 columns as composite primary key in SQLite?

I need to delete some rows in a SQLite table with two columns as primary key, like this:
DELETE FROM apt_lang
WHERE (apt_fk, apt_lang_fk) NOT IN ((42122,"en"),(42123,"es"),(42123,"en"))
This works on Oracle and MySQL but not in SQLite.
Can anybody help me?
First, find out which rows you want to delete.
The easiest way is with a join:
SELECT *
FROM apt_lang
JOIN (SELECT 42122 AS apt_fk, 'en' AS apt_lang_fk UNION ALL
SELECT 42123 , 'es' UNION ALL
SELECT 42123 , 'en' )
USING (apt_fk, apt_lang_fk)
To use this with a DELTE, either check with EXISTS for a match:
DELETE FROM apt_lang
WHERE NOT EXISTS (SELECT 1
FROM apt_lang AS a2
JOIN (SELECT 42122 AS apt_fk, 'en' AS apt_lang_fk UNION ALL
SELECT 42123 , 'es' UNION ALL
SELECT 42123 , 'en' )
USING (apt_fk, apt_lang_fk)
WHERE apt_fk = apt_lang.apt_fk
AND apt_lang_fk = apt_lang.apt_lang_fk)
or get the ROWIDs of the subquery and check against those:
DELETE FROM apt_lang
WHERE rowid NOT IN (SELECT apt_lang.rowid
FROM apt_lang
JOIN (SELECT 42122 AS apt_fk, 'en' AS apt_lang_fk UNION ALL
SELECT 42123 , 'es' UNION ALL
SELECT 42123 , 'en' )
USING (apt_fk, apt_lang_fk))
This should work:
DELETE FROM apt_lang WHERE (apt_fk, apt_lang_fk) NOT IN (VALUES (42122,"en"),(42123,"es"),(42123,"en"))
Yes, it's possible to delete rows from SQLite based on a subquery that builds on multiple columns. This can be done with SQLite's concatenate "||" operator. It might help to show an example.
Setup:
create table a (x,y);
insert into a values ('A','B');
insert into a values ('A','C');
create table b (x,y);
insert into b values ('A','C');
insert into b values ('A','X');
Show Tables:
select * from a;
A|B
A|C
select * from b;
A|C
A|X
Assuming you want to delete from table a rows where column x and column y don't match with table b, the following select will accomplish that.
delete from a where x||y not in (select a.x||a.y from a,b where a.x=b.x and a.y=b.y);
Result:
select * from a;
A|B
Summary
This relies on concatenating several columns into one with the "||" operator. Note, it will work on calculated values too, but it might require casting the values. So, just a few conversions to note with the "||" operator...
select 9+12|| 'test';
21 -- Note we lost 'test'
select cast(9+12 as text)|| 'test';
21test -- Good! 'test' is there.

How to set unique constraint over multiple columns when any one can be null?

How do I set unique constraint over multiple columns when any one can be null in SQLite?
e.g. I have made unique("col1","col2","col3") and tried insert into tablename values("abc","def",null) twice it inserted both rows.
The unique constraint is not working when third column is null.
In sqlite, all null are differences.
I think the best way to solve this issue is to set column c not null with a special default value. Then use the default value (for example 0, '') to represent null.
edit 1
you can easily extend this solution to any columns
create table test (
a text not null default "",
b text not null default "",
c text not null default ""
);
You could create a trigger to enfore this:
CREATE TRIGGER col1_col2_col3null_unique
BEFORE INSERT ON MyTable
FOR EACH ROW
WHEN col1 IS NOT NULL
AND col2 IS NOT NULL
AND col3 IS NULL
BEGIN
SELECT RAISE(ABORT, 'col1/col2/col3 must be unique')
FROM MyTable
WHERE col1 = NEW.col1
AND col2 = NEW.col2
AND col3 IS NULL;
END;
You need such a trigger for each possible combination of NULLs in the three columns.
Furthermore, if it is possible to have UPDATEs that change such a column to NULL, you need triggers for those, too.
Starting with version 3.9.0 (2015-10-14) you can use indexes on expressions (https://www.sqlite.org/expridx.html) and use for example the COALESCE function to transform null values into some form of fallback value:
CREATE UNIQUE INDEX IX_Unique ON Table1 (
COALESCE(col1, ""),
COALESCE(col2, ""),
COALESCE(col3, "")
);

Resources