ANSI equivalent of IS NULL - sql

I am trying to find the ANSI way to write the T-SQL 'IS NULL'. (corrected, was 'IN NULL')
Some posts on the internet say you can use coalesce to make it work like 'IS NULL'
The reason I like to do this: portable code. And the query must return the rows that are NULL.
So far I created this:
SELECT empid,
firstname,
lastname,
country,
coalesce(region,'unknown') AS regions ,
city
FROM HR.Employees
The result set looks like:
empid firstname lastname country regions city
1 Sara Davis USA WA Seattle
2 Don Funk USA WA Tacoma
3 Judy Lew USA WA Kirkland
4 Yael Peled USA WA Redmond
5 Sven Buck UK unknown London
6 Paul Suurs UK unknown London
7 Russell King UK unknown London
8 Maria Cameron USA WA Seattle
9 Zoya Dolgopyatova UK unknown London
I identified the rows that are NULL, but how do I filter them out of this set?

Both IS NULL and COALESCE are ANSI standard and available in almost all reasonable databases. The construct that you want, I think, is:
where region IS NULL
This is standard syntax.
To have COALESCE work like IS NULL requires a value that you know is not in the data:
where coalesce(region, '<null>') <> '<null>'
However, you would need different values for dates and numbers.

You seem to be confusing IS NULL (a predicate that checks to see if a value is null) and the T-SQL specific function ISNULL(value, replace) (no space and parameters after it), which is similar, but not identical to COALESCE.
Please see SQL - Difference between COALESCE and ISNULL? for details on how COALESCE and ISNULL differ for T-SQL.
Minor differences like what type is returned and what happens when all the arguments are null aside, ISNULL is a function that returns the first argument if it is not null, or the second argument if it is. COALESCE returns the first non-null argument (it can take more than two).
As a result, each of these might be used to solve your problem in different ways and with slightly different results.

IS NULL is valid ANSI SQL-92, is called the null predicate.
<null predicate> ::= <row value constructor> IS [ NOT ] NULL
See SQL-92, paragraph 8.6.
So WHEREcolumn nameIS NULL is perfectly valid.
The bit where ANSI SQL treats NULL values different from T-SQL is when you write WHERE column name = NULL or WHERE column name <> NULL. See SET ANSI NULLS (Transact-SQL).

Related

BigQuery - concatenate array of strings for each row with `null`s

This is a clarification/follow-up on the earlier question where I didn't specify the requirement for null values.
Given this input:
Row id app_date inventor.name inventor.country
1 id_1 01-15-2022 Steve US
Ashley US
2 id_2 03-16-2011 Pete US
<null> US
Mary FR
I need to extract name from inventor struct and concatenate them for each id, like so:
Row id app_date inventors
1 id_1 01-15-2022 Steve, Ashley
2 id_2 03-16-2011 Pete, ^, Mary
Note custom filling for null value - which, to me, seems like it means I need to use ARRAY_TO_STRING specifically that supports this.
The closest example I found doesn't work with nulls. How can one do this?
Use below
SELECT * EXCEPT(inventor),
(SELECT STRING_AGG(IFNULL(name, '^'), ', ') FROM t.inventor) inventors
FROM sample t
with output

SQL Combine null rows with non null

Due to the way a particular table is written I need to do something a little strange in SQL and I can't find a 'simple' way to do this
Table
Name Place Amount
Chris Scotland
Chris £1
Amy England
Amy £5
Output
Chris Scotland £1
Amy England £5
What I am trying to do is above, so the null rows are essentially ignored and 'grouped' up based on the Name
I have this working using For XML however it is incredibly slow, is there a smarter way to do this?
This is where MAX would work
select
Name
,Place = Max(Place)
,Amount = Max(Amount)
from
YourTable
group by
Name
Naturally, if you have more than one occurance of a place for a given name, you may get unexpected results.

sql combine two columns that might have null values

This should be an easy thing to do but I seem to keep getting an extra space. Basically what I am trying to do is combine multiple columns into one column. BUT every single one of these columns might be null as well. When I combine them, I also want them to be separated by a space (' ').
What I created is the following query:
select 'All'= ISNULL(Name+' ','')+ISNULL(City+' ','')+ISNULL(CAST(Age as varchar(50))+' ','') from zPerson
and the result is:
All
John Rock Hill 23
Munchen 29
Julie London 35
Fort Mill 27
Bob 29
As you can see: there is an extra space when the name is null. I don't want that.
The initial table is :
id Name City Age InStates AllCombined
1 John Rock Hill 23 1 NULL
2 Munchen 29 0 NULL
3 Julie London 35 0 NULL
4 Fort Mill 27 1 NULL
5 Bob 29 1 NULL
Any ideas?
select 'All'= LTRIM(ISNULL(Name+' ','')+ISNULL(City+' ','')+ISNULL(CAST(Age as varchar(50))+' ','') from zPerson)
SEE LTRIM()
In the data you have posted, the Name column contains no NULLs. Instead, it contains empty strings, so ISNULL(Name+' ','') will evalate to a single space.
The simplest resolution is to change the data so that empty-strings are null. This is appropriate in your case since this is clearly your intention.
UPDATE zPerson SET Name=NULL WHERE Name=''
Repeat this for your City and Age fields if necessary.
Use TRIM() arount the ISNULL() function, or LTRIM() around the entire selected term

Oracle null values

Can somebody please explain the functionality of the below query in oracle db and why is it not returning the last null row. And also please explain me not in functionality in case of null values.
Table Store_Information
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
San Francisco $300 Jan-08-1999
Boston $700 Jan-08-1999
(null) $600 Jan-10-1999
SELECT *
FROM scott.Store_Information
WHERE store_name IN (null)
STORE_NAME SALES DATE
-------------------- -------------------- -------------------------
0 rows selected
SELECT *
FROM scott.Store_Information
WHERE store_name IS null;
NULL can not be "compared" as other (real) values. Therefor you have to use IS NULL or IS NOT NULL.
Here is a series of blog posts regarding this topic: http://momjian.us/main/blogs/pgblog/2012.html#December_26_2012
If the value you are looking for is a null value, the query should be:
SELECT *
FROM scott.Store_Information
WHERE store_name IS NULL;
Oracle NULLS are special:
nothing is equal to null
nothing is NOT equal to null
Since in is equivalent to a = any, this applies to in also.
So, you cannot use NULL in an in or not in clause and expect proper results.
Null is a special value which doesn't follow normal conventions of string or numeric comparison. Evaluating null using these common methods will always evaluate to FALSE unless you use some of the special built in functions.
Select * from Store_Information
where nvl(store_name,'') in ('')
Select * from store_information
where coalesce(store_name, 'Missing') in ('Missing')
Select * from store_information
where store_name is null
If you want your query select field with null value you can :
solution 1 :
use where ... IS NULL ...
solution 2 :
or if you want absolutely use a IN you can use a NVL
eg :
SELECT *
FROM scott.Store_Information
WHERE NVL(store_name, 'NULL_STORE_NAME') IN ('NULL_STORE_NAME')
but in the second case you make the assumption that you can't have a store name named 'NULL_STORE_NAME'... so usually it's better to use solution 1 in my opinion...

Efficient SQL to merge results or leave to client browser javascript?

I was wondering, what is the most efficient way of combining results into a single result.
I want to turn
Num Ani Country
---- ----- -------
22 cows Canada
20 pigs Canada
40 cows USA
34 pigs USA
into:
cows pigs Country
----- ----- -------
22 20 Canada
40 34 USA
I want to know if it would be better to use SQL only or if I should feed the whole query result set to the user. Once given to the user, I could use JavaScript to parse it into the desired format.
Also, I do not know exactly how I would change this into the right format for a SQL query. The only way I can think of approaching this SQL statement is very roundabout with dynamically creating a temporary table.
The operation you're after is called "pivoting" - the PIVOT info page has a little more detail:
SELECT MAX(CASE WHEN t.ani = 'cows' THEN t.num ELSE NULL END) AS cows,
MAX(CASE WHEN t.ani = 'pigs' THEN t.num ELSE NULL END) AS pigs,
t.country
FROM YOUR_TABLE t
GROUP BY t.country
ORDER BY t.country
There should be an efficient way using a 2-D array on the client-side (php) to achieve the pivoting. To address Ken Downs' concerns about byte pushing, a ragged raw pivot data consumes less bytes than a fully materialized 2-D pivot table, the simple case is
cows | pigs | sheep | goats | country
1 null null null Canada
null 2 null null USA
null null 3 null Egypt
null null null 4 England
which is only 4 rows of raw data (each being 3 columns).
Doing it in the front end also solves the issue of dynamic-pivoting. If your number of pivot columns is unknown, then you would require a MySQL procedure to build up a dynamic sql statement of the pattern "MAX(CASE....)" for each column.
There are advantages to doing this on the client side
can be done (at least considered as an alternative)
can be rendered earlier, if the savings in network traffic is significant despite requiring either (1) php pivottable construction or (2) client side javascript
does not require a MySQL procedure for dynamic pivoting