Is there a PostgreSQL equivalent of SQLite's IS operator? - sql

In SQLite, IS is a binary operator that behaves exactly like = except when one or both of the operands are NULL. In the case where both operands are NULL, the IS operator evaluates to TRUE. In the case where one operand is NULL, but not the other, the IS operand evaluates to FALSE.
I was looking for a similar operator in PostgreSQL, but I could not find one. Is there an equivalent of SQLite's IS operator in PostgreSQL? If not, what is the best/least-complicated work-around?
To clarify, SELECT column1 IS column2 ... is allowed in SQLite, but PostgreSQL raises a syntax error.

Try the IS (NOT) DISTINCT FROM operator.

Apparently it's possible in postgresql (see dan04's). The query below would work in SQL Server and other DBMSs where that syntax isn't available.
You can simulate by doing:
WHERE (column1 is NULL and column2 is NULL)
OR column1 = column2

To add to #Derek's answer:
In MySQL you can use the <=> operator to the same effect:
SELECT * FROM table1 WHERE column1 <=> column2

Related

Multiple NVL() alternative - first not null parameter

Currently I have something like that:
NVL(COL1, NVL(COL2, NVL(COL3, NVL(COL4, NVL(COL5, COL6)))))
Is in Oracle 11gR2 any function that returns first NOT NULL parameter ?
Use COALESCE() function , it returns first non null value in expression list.
SELECT COALESCE(col1,col2,col3,col4,col5,col6)
FrOM tableName
Perhaps you are looking for COALESCE()?
Note that COALESCE() is supported on almost all khown databases: Oracle, PostgreSQL, MySQL, MSSQL, SQLite.

Why does check against existing data not cover NULL in SQL Server 2008

This might be the situation in other databases as well but when you make the following query
SELECT * FROM MyTbl WHERE MyColumn != 'Foo'
then any record where MyColumn is, say, 'Bar' is fetched but not where MyColumn is NULL. I assume this is expected behavior and that there is a reason behind it and I'd like to know why.
Is NULL considered to be equal to 'Foo' or is it just not expected to be part of the condition because the condition (NULL != 'Foo') seems to be true.
In DB logic, NULL means that there is simply no defined data in this field. It's considered neither equal or different to anything. You have to filter on it explicitly if you want to fetch the relevant lines :
SELECT * FROM MyTbl WHERE MyColumn != 'Foo' OR MyColumn IS NULL
See Wikipedia.
In SQL Server works three-state logic, which mean that NULL = NULL UNKNOWN which treats as FALSE
In all relational databases, the null value is not equal to anything, including itself.
You would not be able to find the rows with null values for MyColumn even if your query was "select * from MyTbl where MyColumn = null". The only way to get them would be "select * from MyTble where MyColumn is null"
For a detailed explanation, see http://en.wikipedia.org/wiki/Null_(SQL)
Yep, as Tim commented, NULL values are unknown. SQL Server isn't going to make an assumption about a NULL value in order to make a match. You can check out more info about how SQL Server processes NULLs.

Can SQL SUM() function take an expression as argument?

I'm using SQLite database and I'm wondering whether I'm allowed to write queries as follows:
SELECT SUM(column1 * column2)
FROM my_table;
I googled but references say that SUM function is has the following format:
SUM([DISTINCT|ALL] column)
And my question is: does column mean actually column or does it allow expressions (like above) too?
You can always use a table expression:
SELECT SUM(Calc)
FROM (
SELECT Column1 * Column2 AS 'Calc'
FROM My_Table) t
I don't have SQLite but checking the docs indicates this should work fine.
Yes, you can use an expression like the one you mentioned, if the datatype of both columns allow it.

UPPER() and LOWER() not required?

For a while I thought, in order for the WHERE criteria to be evaluated correctly, I need to account for case sensitivity. I would use UPPER() and LOWER() when case didn't matter. However, I am finding the below queries produce the same result.
SELECT * FROM ATable WHERE UPPER(part) = 'SOMEPARTNAME'
SELECT * FROM ATable WHERE part = 'SOMEPARTNAME'
SELECT * FROM ATable WHERE part = 'somepartname'
SQL Case Sensitive String Compare explains to use case-sensitive collations. Is this the only way to force case sensitivity? Also, if you had a case-insensitive collation when would UPPER() and LOWER() be necessary?
Thanks for help.
The common SQL Server default of a case-insensitive collation means that UPPER() and LOWER() are not required when comparing strings.
In fact an expression such as
SELECT * FROM Table WHERE UPPER(part) = 'SOMEPARTNAME'
is also non-sargable i.e won't use available indexes, due to the function applied to the part column on the left hand side of the comparison.
this query below produces CASE SENSITIVE search:
SELECT Column1
FROM Table1
WHERE Column1 COLLATE Latin1_General_CS_AS = 'casesearch'
UPPER() and LOWER() are only functions to change the case of the letter so if you case-insensitive collation, they are only use after the SELECT Keyword:
SELECT UPPER('qwerty'), LOWER('Dog')
returns
QWERTY, dog

Comparisons with NULLs in SQL

ANSI-92 SQL mandates that comparisons with NULL evaluate to "falsy," eg:
SELECT * FROM table WHERE field = NULL
SELECT * FROM table WHERE field != NULL
Will both return no rows because NULL can't be compared like that. Instead, the predicates IS NULL and IS NOT NULL have to be used instead:
SELECT * FROM table WHERE field IS NULL
SELECT * FROM table WHERE field IS NOT NULL
Research has shown me that Oracle 1, PostgreSQL, MySQL and SQLite all support the ANSI syntax. Add to that list DB2 and Firebird.
Aside from SQL Server with ANSI_NULLS turned off, what other RDBMS support the non-ANSI syntax?
1 The whole empty string = NULL mess notwithstanding.
For what it's worth, comparing something to NULL is not strictly false, it's unknown. Furthermore, NOT unknown is still unknown.
ANSI SQL-99 defines a predicate IS [NOT] DISTINCT FROM. This allows you to mix nulls and non-null values in comarisons, and always get a true or false. Null compared to null in this way is true, otherwise any non-null compared to null is false. So negation works as you probably expect.
PostgreSQL, IBM DB2, and Firebird do support IS [NOT] DISTINCT FROM.
MySQL has a similar null-safe comparison operator <=> that returns true if the operands are the same and false if they're different.
Oracle has the hardest path. You have to get creative with use of NVL() or boolean expressions:
WHERE a = b OR (a IS NULL AND b IS NULL)
Yuck.
Here is a nice comparison of null handling in SQLite, PostgreSQL, Oracle, Informix, DB2, MS-SQL, OCELOT, MySQL 3.23.41, MySQL 4.0.16, Firebird, SQL Anywhere, and Borland Interbase