Not calculating exponential and log functions in Oracle - oracle

I am having some challenges with exponential and log functions in Oracle in that I am not getting the expected answer to the formula below -I should be getting 10.97 bur rather I am getting 32.77
The formula is given as
M = exp(-8.758548 + 2.151173· ln(height) - 0.027927·ln (age) + Mspline)
Any assistance much appreciated -Code is as follows-
with samp as (select 1 as ID,178 as ht,30 as age, 0.101788 as MSPLINE
from dual)
select
exp(-7.664278+2.151173*ln(samp.ht)-0.027927*ln(samp.age)+Mspline) from samp;

Related

dbms_random.value() in Snowflake - Oracle to snowflake conversion

Below is the oracle sql query that I got to convert to snowflake. In here, i am blocked in creating dbms_random.value() in snowflake
select emp_id, emp_name, emp_mob,
(case when dbms_random.value() >= 0.85 then 'Y' else 'N' end) as tag
from eds_dwg.employee_data
Can someone help me on this?
Thanks
You can use Snowflake Data generation functions: https://docs.snowflake.com/en/sql-reference/functions-data-generation.html
NORMAL() returns a floating point number with a specified mean and standard deviation. Something like this with correct adaptions of the parameters could to the trick: https://docs.snowflake.com/en/sql-reference/functions/normal.html
An alternative can be using UNIFORM(): https://docs.snowflake.com/en/sql-reference/functions/uniform.html
Example from docs to generate a value between 0 and 1:
select uniform(0::float, 1::float, random()) from table(generator(rowcount => 5));

How to retrieve currency amount as words using oracle sql

In the below code, I am trying to get the amount in words for the value in the AMOUNT column but can't seem to get it right. Anyone with an idea? Below the CREATE VIEW statement:
SELECT GLR3 AS RECEIPT_DOC_NO,
GLANI AS ACCOUNT_NUMBER,
GLSBL AS JDE_NO,
(SELECT YAALPH FROM PRODDTA.F060116 WHERE YAAN8 = T1.GLSBL) AS STAFF_NAME,
CASE GLDGJ WHEN 0 THEN TO_DATE (TO_CHAR (1 + 1900000), 'YYYYDDD')
ELSE TO_DATE (TO_CHAR (GLDGJ + 1900000), 'YYYYDDD') END AS GL_DATE,
GLEXA AS NARRATIVE,
GLLT AS LEDGER_TYPE,
GLSBLT AS SUBLEDGER_TYPE,
GLCRCD AS CURRENCY_CODE,
CASE GLAA WHEN 100 THEN ROUND (GLAA / 100, 2) ELSE ROUND (GLAA / 100, 2)
END AS AMOUNT,
(SELECT TO_CHAR(TO_DATE(T1.GLAA,'J'),'JSP')) FROM DUAL) AS AMOUNT_INWORDS
FROM PRODDTA.F0911 T1;
My code is failing with
ORA-00923: FROM keyword not found where expected.
ORA-00923: FROM keyword not found where expected.
Indicates a syntax error. In this case you have three ( and four ):
(SELECT TO_CHAR(TO_DATE(T1.GLAA,'J'),'JSP')) FROM DUAL) AS AMOUNT_INWORDS
The compiler is not expecting the second ) after 'JSP'.
The scalar cursor is unnecessary, so the simplified and corrected version would be:
TO_CHAR(TO_DATE(T1.GLAA,'J'),'JSP') AS AMOUNT_INWORDS
ORA-01854: julian date must be between 1 and 5373484
5373484 is the Julian date for 31-DEC-9999 which is the maximum date allowed in Oracle. This poses an absolute limit on the number which we can spell using JSP mask ... in one go. However, we can use PL/SQL to break larger numbers into chunks and spell those instead. The inestimable Tom Kyte wrote such a function and published it on the AskTom site. Find it here.
I think the value i'm trying to write in words has decimal values (400.00) hence the ORA-01854 error.
The Tom Kyte I linked to does address that issue further down the page. It's this comment here.
Data retrieved in amount column is preceded by a negative symbol when it shouldn't be,
If you simply want to ignore negative values then apply the ABS() function to give you the absolute value.

stddev function in plsql is giving me the wrong value

I need to calculate the stddev function in plsql, but when I compared the values with java program, it is different.
I need to get the stddev function for this set of values(100,104,105,103,110,115,130,95,91,105,106,101,65,91,95), when I used plsql the value is : 14.032 and using java it is 13.557. could you please help in getting the correct value using oracle plsql
Here is an explicit SQL query which takes your numbers and steps them through the Standard Deviation calculation.
with t23 as (
select column_value as val
from table (sys.odcinumberlist(100,104,105,103,110,115,130,95,91,105,106,101,65,91,95))
)
, mn as (
select avg(val) as avg_val
, count(*) as cnt
from t23
) , inp as (
select t23.val
, t23.val - mn.avg_val as diff
, power(t23.val - mn.avg_val , 2) diff_sq
, mn.cnt
from t23 cross join mn
)
select sum(diff_sq) as sum_diff_sq
, sqrt( sum(diff_sq) / (cnt-1) ) as sd
from inp
group by cnt
;
The value of SD is 14.0329544118054 which suggests the Oracle stddev() function is correct and whatever you're running in Java is incorrect.
Great code there #APC - I like the look through nature of the code :)
So I came across this same issue today and the answer is Oracle has two built-in functions for Standard Deviation according to the two distinct calculations:
a) stddev - for standard deviation sample; and
b) stddev_pop standard deviation population
select stddev(column_value), stddev_pop(column_value)
from table (sys.odcinumberlist(100,104,105,103,110,115,130,95,91,105,106,101,65,91,95))
Example
STDDEV(COLUMN_VALUE) STDDEV_POP(COLUMN_VALUE)
-------------------- ------------------------
14.0329544 13.5571219
So use the one that suits your needs...
Some info on standard deviations and which one to use here.

Dynamic order by date data type in Oracle using CASE

My code in the stored procedure:
SELECT * FROM
my_table ir
WHERE
--where clause goes here
ORDER BY
CASE WHEN p_order_by_field='Id' AND p_sort_order='ASC' THEN IR.ID end,
CASE WHEN p_order_by_field='Id' AND p_sort_order='DESC' THEN IR.ID end DESC,
CASE WHEN p_order_by_field='Date' AND p_sort_order='ASC' THEN TO_CHAR(IR.IDATE, 'MM/dd/yyyy') end,
CASE WHEN p_order_by_field='Date' AND p_sort_order='DESC' THEN TO_CHAR(IR.IDATE, 'MM/dd/yyyy') end DESC;
Problem is that sorting is done based on the char, which comes out wrong for the date case. CASE statement, however, won't allow any other datatype other than char. So what is the solution in this case? I need to be able to pass the p_order_by_field into the stored procedure.
Thanks
Should be simple - just use ISO date format in your case:
TO_CHAR(IR.IDATE, 'yyyy-mm-dd')
and you should be fine.
Another problem could occure when you want to sort on the date difference (let say number of days between two days).
For example such a sort would return number 13 (days) before 9 (days).
The solution is that you concatenate length of date difference and the difference itself:
length(trunc(date2) - trunc(date1)) || to_char(date2 - date1)

Oracle Analytic Question

Given a function zipdistance(zipfrom,zipto) which calculates the distance (in miles) between two zip codes and the following tables:
create table zips_required(
zip varchar2(5)
);
create table zips_available(
zip varchar2(5),
locations number(100)
);
How can I construct a query that will return to me each zip code from the zips_required table and the minimum distance that would produce a sum(locations) >= n.
Up till now we've just run an exhaustive loop querying for each radius until we've met the criteria.
--Do this over and over incrementing the radius until the minimum requirement is met
select count(locations)
from zips_required zr
left join zips_available za on (zipdistance(zr.zip,za.zip)< 2) -- Where 2 is the radius
This can take a while on a large list. It feels like this could be done with an oracle analytic query along the lines of:
min() over (
partition by zips_required.zip
order by zipdistance( zips_required.zip, zips_available.zip)
--range stuff here?
)
The only analytic queries I have done have been "row_number over (partition by order by)" based, and I'm treading into unknown areas with this. Any guidance on this is greatly appreciated.
This is what I came up with :
SELECT zr, min_distance
FROM (SELECT zr, min_distance, cnt,
row_number() over(PARTITION BY zr ORDER BY min_distance) rnk
FROM (SELECT zr.zip zr, zipdistance(zr.zip, za.zip) min_distance,
COUNT(za.locations) over(
PARTITION BY zr.zip
ORDER BY zipdistance(zr.zip, za.zip)
) cnt
FROM zips_required zr
CROSS JOIN zips_available za)
WHERE cnt >= :N)
WHERE rnk = 1
For each zip_required calculate the distance to the zip_available and sort them by distance
For each zip_required the count with range allows you to know how many zip_availables are in the radius of that distance.
filter (first where COUNT(locations) > N)
I used to create sample data:
INSERT INTO zips_required
SELECT to_char(10000 + 100 * ROWNUM) FROM dual CONNECT BY LEVEL <= 5;
INSERT INTO zips_available
(SELECT to_number(zip) + 10 * r, 100 - 10 * r FROM zips_required, (SELECT ROWNUM r FROM dual CONNECT BY LEVEL <= 9));
CREATE OR REPLACE FUNCTION zipdistance(zipfrom VARCHAR2,zipto VARCHAR2) RETURN NUMBER IS
BEGIN
RETURN abs(to_number(zipfrom) - to_number(zipto));
END zipdistance;
/
Note: you used COUNT(locations) and SUM(locations) in your question, I assumed it was COUNT(locations)
SELECT *
FROM (
SELECT zip, zd, ROW_NUMBER() OVER (PARTITION BY zip ORDER BY rn DESC) AS rn2
FROM (
SELECT zip, zd, ROW_NUMBER() OVER (PARTITION BY zip ORDER BY zd DESC) AS rn
FROM (
SELECT zr.zip, zipdistance(zr.zip, za.zip) AS zd
FROM zips_required zr
JOIN zips_available za
)
)
WHERE rn <= n
)
WHERE rn2 = 1
For each zip_required, this will select the minimal distance into which fit N zip_available's, or maximal distance if the number of zip_available's is less than N.
I solved the same problem by creating a subset of ZIP's within a square radius from the given zip (easy math: < or > NSWE radius ), then iterating through each entry in the subset to see if it was within the needed radius. Worked like a charm and was very fast.
I had partly similar requirements in one of my old projects... to calculate distance between 2 zipcodes in the US. To solve the same I had made great use of US Spatial Data. Basically the approach was to get the Source Zipcode(Latitude, Longitude) and Destination Zipcode(Latitude, Longitude).
Now then I had applied a function to get the distance based on the above. The base formula that helps in doing this calculation is available in the following site
I had also validated the outcome by referring to this site...
Note: However this will provide approximate distances, so one can use this accordingly. Benefits are once constructed its superfast to fetch the results.

Resources