DuckDB provides us with a good selection of list functions. This includes a list_any_value() function, which returns the first non-NULL value from a given list.
Syntax
list_any_value(list)
So the function accepts a single argument; the list.
Example
Here’s a simple example to demonstrate:
SELECT list_any_value( [ NULL, 'Red', 'Green', 'Blue' ] );
Result:
Red
We can see that it skipped the NULL value and took the first value after that.
Multiple NULLs
If there are multiple NULL values, then they’re all skipped until the first non-NULL value is found:
SELECT list_any_value( [ NULL, NULL, NULL, 'Red', 'Green', 'Blue' ] );
Result:
Red
When All Values are NULL
If all of the list’s values are NULL, then NULL is returned:
.nullvalue 'null'
SELECT list_any_value( [ NULL, NULL, NULL ] );
Result:
null
Here, I used .nullvalue 'null' in my DuckDB CLI in order to output null whenever a NULL value is returned. Without doing this, the CLI would return an empty string whenever a NULL value is returned. That would make it difficult for us to tell whether or not a NULL value is actually being returned, hence the .nullvalue 'null'.
Passing an Empty List
Passing an empty list results in NULL being returned:
SELECT list_any_value( [ ] );
Result:
null
Passing the Wrong Argument Type
If the argument is not a list, then an error occurs:
SELECT list_any_value( 'Red' );
Result:
Binder Error: No function matches the given name and argument types 'list_aggr(STRING_LITERAL, STRING_LITERAL)'. You might need to add explicit type casts.
Candidate functions:
list_aggr(ANY[], VARCHAR, [ANY...]) -> ANY
LINE 1: SELECT list_any_value( 'Red' );
^
Nested Lists
If the first non-NULL value is a list, then that list is returned:
SELECT list_any_value( [NULL, NULL, [ NULL, 'Red', 'Green', 'Blue' ]] );
Result:
[NULL, Red, Green, Blue]
Bear in mind that the list is still returned, even if it contains nothing but NULL values:
SELECT list_any_value([
[ NULL, NULL],
[ NULL, 'Red', 'Green', 'Blue' ]
]);
Result:
[NULL, NULL]
However, it’s possible to use the flatten() function to flatten lists if required:
SELECT list_any_value(
flatten([
[ NULL, NULL],
[ NULL, 'Red', 'Green', 'Blue' ]
])
);
Result:
Red
We can also use the unnest() function, depending on our requirements:
SELECT list_any_value(
unnest([
[ NULL, NULL],
[ NULL, 'Bird'],
[ NULL, 'Red', 'Green', 'Blue' ]
])
) AS unnested;
Result:
+----------+
| unnested |
+----------+
| null |
| Bird |
| Red |
+----------+