Simple Math max function in MySQL - sql

How to find the maximum of two explicit values in MySQL? Something like MAXIMUM(1, #foo).
There are group functions like MAX, MIN, AVG, etc that take column name as an argument and work with result sets. Is it possible to convert two explicit values to a result set and use those functions? Some other ways?
P.S.: I need a max function for one of my stored procedures.

How to find the maximum of two explicit values in MySQL? Something like MAXIMUM(1, #foo).
Use the GREATEST function:
GREATEST(1, #foo)
...will return whichever value is larger - if 1 is larger than the value in #foo, you'll get 1. Otherwise, you'll get whatever value is in #foo. Also, it's not an aggregate function.
The alternative would be to use a CASE statement:
CASE WHEN 1 > #foo THEN 1 ELSE #foo END
...because CASE is ANSI standard - that will work on Oracle, MySQL, SQL Server, Postgres...

You can use IF(1 > #foo,1,#foo)

Related

SQL function to transform number with a certain pattern

I need for a SQL query to transform an int with a value between 1 to 300000 to a number which has this pattern : always 8 number.
For example:
1 becomes 00000001,
123 becomes 00000123,
123456 becomes 00123456.
I have no idea how to do that... How can I do it?
In Standard SQL, you can use this trick:
select substring(cast( (num + 100000000) as varchar(255)) from 2)
Few databases actually support this syntax. Any given database can do what you want, but the method depends on the database you are using.
For MS SQL Server
You could use FORMAT function, like this:
SELECT FORMAT(123,'00000000')
https://database.guide/how-to-format-numbers-in-sql-server/#:~:text=Starting%20from%20SQL%20Server%202012,the%20output%20should%20be%20formatted.
Read at the link Leading Zeroes
For MySql/Oracle
You could use LPAD, like this:
SELECT LPAD('123',8,'0')
https://database.guide/how-to-add-leading-zeros-to-a-number-in-mysql/

SQL: AVG with NULL Values

As far as I understood, the AVG() function ignores NULL Values.
So AVG(4,4,4,4,4,NULL) --> 4
In my case I don't want this to happen.
I need a solution like that: AVG(4,4,4,4,4,NULL) --> 3,33
without replacing the NULL values directly in the table itself.
Is there any way to do this?
Use coalesce() to return the real value of zero for null columns:
select avg(coalesce(some_column, 0))
from ...
You are correct about the behavior of AVG - use COALESCE to convert the NULLs to 0 in the aggregate.
See this answer in "Why SUM(null) is not 0 in Oracle?"
If you are looking for a rationale for this behaviour, then it is to be found in the ANSI SQL standards which dictate that aggregate operators ignore NULL values.
The relevant code is then, simply:
Avg(Coalesce(col,0))
You can use coalesce or nvl also.
Since coalesce examples are already given above, here is an example of nvl
Avg(Nvl(Column_Name),0)
Coalesce, Nvl, Nvl2 functions are handy in such cases of handling null values.
You should look up some examples and documentation on these.
NVL, NVL2, or COALESCE could be used to solve this issue.
like this
select avg(4,4,4,4, nvl(null, 0 )) from dual;
Another possibility is to calculate average using aggregate functions SUM with COUNT
SELECT SUM(column_with_value) / COUNT(primary_column) FROM ...

Absolute maxvalue comparison of columns in Firebird SQL

I want to perform comparison for the specified columns in database, the comparison logic should compare the numbers regardless of their signs and will retrieve the result original with its sign.
For example, below code works well but as can be seen in the select block it returns the absolute value of columns. Is there any trick, cheat in Firebird 2.1 to overcome that?
SELECT a.ELM_NUM,a.COMBO, maxvalue(abs(a.N_1),abs(a.N_2)) as maxN from ntm a order by a.ELM_NUM
You can use a CASE condition:
SELECT a.ELM_NUM,a.COMBO,
CASE WHEN abs(a.N_1) > abs(a.N_2) THEN a.N_1 ELSE a.N_2 END as maxN
from ntm a
order by a.ELM_NUM

Scalar Max in Sql Server

How to implement the scalar MAX in Sql server (like Math.Max). (In essense I want to implement something like Max(expression, 0), to make negative values replaced by 0.)
I've seen in other threads solutions with
creating a scalar function (how's that with performance?)
case when expression > 0 THEN expression ELSE 0) (then 'expression' is evaluated twice?)
complicated uses of
Max(aggregate).
What's the best?
Why does Sql Server not have something like this built in? Any complications I don't see?
In all other major systems this function is called GREATEST.
SQL Server seriously lacks it.
You can make a bunch of case statements, or use something like this:
SELECT (
SELECT MAX(expression)
FROM (
SELECT expression
UNION ALL
SELECT 0
) q
) AS greatest
FROM table_that_has_a_field_named_expression
The latter one is a trifle less performant than CASE statements.
you want to create a user-defined scalar function named MAX in sql server to take two parameters as input, an expression and a min value, and return the expression if it exceeds the min value, otherwise return the min value?
I wouldn't worry about the performance of scalar functions, let the server do that.
I'd also use IF instead of CASE to test for > min value.
SQL server doesn't have a built in function for you because they didn't think it would be widely enough used, I guess.
The query optimizer should prevent the expression from being calculated multiple times.
For readability / maintainability, consider using a CTE to calculate the expression before the CASE statement.

Is there a 'greatest' function in db2?

I found in MYSQL and apparently other database engines that there is a "greatest" function that can be used like: greatest(1, 2, 3, 4), and it would return 4. I need this, but I am using IBM's DB2. Does anybody know of such an equivalent function, even if it only accepts 2 parameters?
I found somewhere that MAX should do it, but it doesn't work... it only works on selecting the MAX of a column.
If there is no such function, does anybody have an idea what a stored procedure to do this might look like? (I have no stored procedure experience, so I have no clue what DB2 would be capable of).
Why does MAX not work for you?
select max(1,2,8,3,1,7) from sysibm.sysdummy1
gives me
1
---------------
8
1 record(s) selected.
As Dave points out, MAX should work as it's overloaded as both a scalar and a column function (the scalar takes 2 or more arguments). This is the case in DB2 for LUW, DB2 for z/OS and DB2 for i5/OS. What exact version and platform of DB2 are you using, and what is the exact statement you are using? One of the requirements of the scalar version of MAX is that all the arguments are "compatible" - I suspect there may be a subtle type difference in one or more of the arguments you're passing to the function.
On Linux V9.1, the "select max (1,2,3) ..." gives -
SQL0440N No authorized routine named "MAX" of type "FUNCTION" having
compatible arguments was found. SQLSTATE=42884
It is a scalar function requiring either a single value or a single column name. On z/os, it behaves differently.
However, It does work as expected on Linux 9.5.
Two options:
What about sorting the column in descending and grabbing the top 1 row?
According to my "SQL Pocket Guide", MAX(x) returns the greatest value in a set.
UPDATE: Apparently #1 won't work if you are looking at columns.
It sounds crazy, but no such function exists in DB2, at least not in version 9.1. If you want to select the greater of two columns, it would be best to use a case expression.
You can also define your own max function. For example:
create function importgenius.max2(x double, y double)
returns double
language sql
contains sql
deterministic
no external action
begin atomic
if y is null or x >= y then return x;
else return y;
end if;
end
Defining the inputs and outputs as doubles lets you take advantage of type promotion, so this function will also work for integers. The "deterministic" and "no external action" statements help the database engine optimize use of the function.
If you want another max function to work for character inputs, you'll have to give it another name.
Please check with following query:
select * from table1 a,
(select appno as sub_appno,max(sno) as sub_maxsno from table1 group by appno) as tab2
where a.appno =tab2.sub_appno and a.sno=tab2.sub_maxsno