Set a maximum value for an expression - sql

I am trying to create a score based on the char_length of a field. I am using a fraction of the char_length returned.
(CASE WHEN (char_length(e.summary)/100) is null THEN +0
ELSE +(char_length(e.summary)/100) END)
I would like to know how to set a maximum return value. Is there a simple function or do I need to do one more CASE WHEN with if >=10 THEN ... ?

Simplify to:
LEAST(COALESCE(length(e.summary)/100, 0), 10)
Use LEAST() to introduce an upper border as #Mark already mentioned.
Use COALESCE() to provide a default for NULL values.
length() does the same as char_length()

You can use the least function.
least(<YOUR CALC HERE>, 10) limits the maximum value returned to 10.

Related

If output comes in negative value, how to make it null?

Hi I am working on one query, what I want to do is, whenever output comes in negative value,
I want to make it null, following is my query, can anyone help me with this ?
select (to_char((coalesce(14515200/3600000,0) - (coalesce(30512.65/3600,0) - (coalesce(1800/3600,0) + (coalesce(1800/3600,0))))),'FM99,999,999,999'))::character varying as test
If you want a result of NULL for negative values, use
nullif(greatest(/* your expression */, 0), 0)
The only drawback here is that a result of exactly 0 will also become NULL. If you want to avoid that, you could use a user defined function:
CREATE FUNCTION neg_to_null(double precision) RETURNS double precision
LANGUAGE plpgsql AS
'BEGIN; RETURN CASE WHEN $1 < 0.0 THEN NULL ELSE $1; END;';
I use PL/pgSQL to avoid function inlining.
Move your logic to the from clause and use case:
select (case when test_n >= 0 then test_n::character varying end)
from (select . . . as test_n -- your expression as number) x
If your expression actually uses values from a table, you can use a subquery, CTE, or lateral join to define test_n.

Hive casting function

In a hive table how can I add the '-' sign in a field, but for random records? If I use the syntax below it changes all the records in the field to negative, but I want to change random records to negative.
This is the syntax I used which changed all the records to negative:
CAST(CAST(-1 AS DECIMAL(1,0)) AS DECIMAL(19,2))
*CAST(regexp_replace(regexp_replace(TRIM(column name),'\\-',''),'-','') as decimal(19,2)),
If you want to change random values to negative, why not use a case expression?
select (case when rand() < 0.5 then - column_name else column_name end)
Despite your query, this assumes that the column is a number of some sort, because negating strings doesn't make much sense.

Avoid division by zero in PostgreSQL

I'd like to perform division in a SELECT clause. When I join some tables and use aggregate function I often have either null or zero values as the dividers. As for now I only come up with this method of avoiding the division by zero and null values.
(CASE(COALESCE(COUNT(column_name),1)) WHEN 0 THEN 1
ELSE (COALESCE(COUNT(column_name),1)) END)
I wonder if there is a better way of doing this?
You can use NULLIF function e.g.
something/NULLIF(column_name,0)
If the value of column_name is 0 - result of entire expression will be NULL
Since count() never returns NULL (unlike other aggregate functions), you only have to catch the 0 case (which is the only problematic case anyway). So, your query simplified:
CASE count(column_name)
WHEN 0 THEN 1
ELSE count(column_name)
END
Or simpler, yet, with NULLIF(), like Yuriy provided.
Quoting the manual about aggregate functions:
It should be noted that except for count, these functions return a
null value when no rows are selected.
I realize this is an old question, but another solution would be to make use of the greatest function:
greatest( count(column_name), 1 ) -- NULL and 0 are valid argument values
Note:
My preference would be to either return a NULL, as in Erwin and Yuriy's answer, or to solve this logically by detecting the value is 0 before the division operation, and returning 0. Otherwise, the data may be misrepresented by using 1.
Another solution avoiding division by zero, replacing to 1
select column + (column = 0)::integer;
If you want the divider to be 1 when the count is zero:
count(column_name) + 1 * (count(column_name) = 0)::integer
The cast from true to integer is 1.

What does this SQL Query mean?

I have the following SQL query:
select AuditStatusId
from dbo.ABC_AuditStatus
where coalesce(AuditFrequency, 0) <> 0
I'm struggling a bit to understand it. It looks pretty simple, and I know what the coalesce operator does (more or less), but dont' seem to get the MEANING.
Without knowing anymore information except the query above, what do you think it means?
select AuditStatusId
from dbo.ABC_AuditStatus
where AuditFrequency <> 0 and AuditFrequency is not null
Note that the use of Coalesce means that it will not be possible to use an index properly to satisfy this query.
COALESCE is the ANSI standard function to deal with NULL values, by returning the first non-NULL value based on the comma delimited list. This:
WHERE COALESCE(AuditFrequency, 0) != 0
..means that if the AuditFrequency column is NULL, convert the value to be zero instead. Otherwise, the AuditFrequency value is returned.
Since the comparison is to not return rows where the AuditFrequency column value is zero, rows where AuditFrequency is NULL will also be ignored by the query.
It looks like it's designed to detect a null AuditFrequency as zero and thus hide those rows.
From what I can see, it checks for fields that aren't 0 or null.
I think it is more accurately described by this:
select AuditStatusId
from dbo.ABC_AuditStatus
where (AuditFrequency IS NOT NULL AND AuditFrequency != 0) OR 0 != 0
I'll admit the last part will never do anything and maybe i'm just being pedantic but to me this more accurately describes your query.
The idea is that it is desireable to express a single search condition using a single expression but it's merely style, a question of taste:
One expression:
WHERE age = COALESCE(#parameter_value, age);
Two expressions:
WHERE (
age = #parameter_value
OR
#parameter_value IS NULL
);
Here's another example:
One expression:
WHERE age BETWEEN 18 AND 65;
Two expressions
WHERE (
age >= 18
AND
age <= 65
);
Personally, I have a strong personal perference for single expressions and find them easier to read... if I am familiar with the pattern used ;) Whether they perform differently is another matter...

SQLite equivalent of PostgreSQL's GREATEST function

PostgreSQL has a useful function called GREATEST. It returns the largest value of those passed to it as documented here.
Is there any equivalent in SQLite?
As a note, I only need it to work with 2 arguments.
SELECT MAX(1,2,..)
ref: https://sqlite.org/lang_corefunc.html#maxoreunc
max(X,Y,...)
The multi-argument max() function returns the argument with the maximum value, or return NULL if any argument is NULL. The multi-argument max() function searches its arguments from left to right for an argument that defines a collating function and uses that collating function for all string comparisons. If none of the arguments to max() define a collating function, then the BINARY collating function is used. Note that max() is a simple function when it has 2 or more arguments but operates as an aggregate function if given only a single argument.
using a second value in MAX(value1, value2) would be the equivalent
Example:
UPDATE products SET Quantity = MAX(Quantity - #value, 0)...
if (Quantity - value) return a "Negative Number -0" then Max( , 0) will return 0 because 0 is bigger than -0 / -1 / -2 ... and so on
Max( , 1) will return 1 if the same condition (Quantity - value) return 0 or a Negative Number .. etc, you get the idea !
if we assume that both Quantity and #value could be NULL then use the combination: IFNULL(MAX(Quantity-#value,0),0)
IFNULL(..., 0) will return the second value of your choice IF the first one is NULL