How can I use scientific notation in SQL scripts - sql

I am creating a database in which certain derived attributes are computed using the Universal Gravitational Constant (G), whose approximate value is 6.673 * 10^-11.
I understand that a normal integer constant can be defined using a scalar function as follows
CREATE FUNCTION MY_CONST()
RETURNS INT
AS
BEGIN
RETURN 123456789
END
Thing is, I'm new to SQL and not sure how to store a complex value such as G in there. In popular high-level programming languages like Java, I usually define the value as 6.673e-11 at the top of the editor and call it whenever I need it in my calculations. I would like to know how to simply do the same in SQL.
I really just don't get how to translate the value into SQL code as a constant.

Related

Postgres pg_trgm how to compare similarity for array of strings

I'm attempting to use pg_trgm for string fuzzy matching and I know it may be used like this:
SELECT * FROM artists WHERE SIMILARITY(name, 'Claud Monay') > 0.4;
where a scalar value may be used to compare against the similarity. However, I've seen this way of using SIMILARITY with an array of strings:
SELECT * FROM artists WHERE 'Cadinsky' % ANY(STRING_TO_ARRAY(name, ' '));
which uses the % operator which is a shorthand for comparing against the default value of 0.3. I'm trying to find the proper syntax to use ANY(STRING_TO_ARRAY(...)) but with the first form where an arbitrary scalar value may be given to compare the similarity against.
This is, most likely, just a simple question of properly using the syntax for ANY, but I'm failing at understanding what the correct form is.
There is no syntax to use ANY with 3 arguments (the string, the array of strings, and the similarity threshold). The way to do it is to set pg_trgm.similarity_threshold to the value you want rather than the default of 0.3, and then use % ANY.
If you want to use different thresholds in different parts of the query, you are out of luck with the ANY construct.
You can always define your own function, but you will probably not be able to get it to use an index.
create or replace function most_similar(text, text[]) returns double precision
language sql as $$
select max(similarity($1,x)) from unnest($2) f(x)
$$;
SELECT * FROM artists WHERE most_similar('Cadinsky', STRING_TO_ARRAY(name, ' '))>0.4;
I am not a DB expert nor good at SQL but here is my solution.
I basically use a function called unnest(). Thus, I can iterate over the array and check the similarity value for each item then compare it to similarity input, which is a float.
Using something like set pg_trgm.similarity_threshold=0.6; is a global setting as far as I know. The question is specifically asking for an explicit threshold.
Also, if you create a function to do the job and the function is not VOLATILE but is STABLE, you cannot use set pg_trgm.similarity_threshold. (At least that was what happened to me).
Caution: I didn't compare my approach to (ANY) approach in terms of performance.
Example Code:
CREATE OR REPLACE FUNCTION your_function_name (input text, similarity float) RETURNS
SELECT * FROM your_table_name
WHERE EXISTS
(SELECT
FROM unnest(ARRAY['item','anotherItem', 'third-ish']) element
WHERE SIMILARITY (input, element) > similarity
);
$ function $

Custom functions in SQL

how would I implement custom functions in SQL?
Let's say I have a list of values and I want to transform those in a way where SQL doesn't supply a default function. E.g. look at every field's string, count the number of chars and add the sum of it to the end of each string.
In a programming language this is easy, e.g. save the field's string in a variable A, loop through the string char by char and increasing a counter by one each time, adding the counter to variable A.
But how would I do this in SQL? Can I implement EVERY function solely with the means of SQL, or do I need to use a common programming language like Java, or something like PL/SQL for that?
Thanks so much.

Is it possible to use a generic identifier in a SELECT query in SQLite?

I'm creating a function for querying a SQLite database that should be generic in the sense of reading from multiple pre-defined tables. As part of the function's paremeters, it is necessary to tel which column of the table should be read, an info that is supposed to be passed by an enumerator value. So the call would be something like this:
callMyFunction(enumTableA,enumColumnB);
Since enumColumnB is an enumerator value, the argument is an integer and I would like to identify the column by that integer value without having to use a switch-case for that. Something like this:
SELECT column(enumColumnB) from ...
So instead of passing the name of the column or reading all columns with * and then selecting the desired one when reading, it would use the number of the column as passed by the enumerator value to identify what should be read.
Is it possible to do this for SQLite? I couldn't find any tutorial mentioning such possibility, so I'm almost concluding there is no such possibility (and I'll have to pass the name of the column as argument or use a switch-case at the end), but I'ld like to be sure I don't have this option available.
SQLite has no mechanism for indirect columns.
(SQLite is designed as an embedded database, i.e., to be used together with a 'real' programming language.)
You have to replace the column name in whatever programming language you're using.

PROC SQL error: "ERROR: Expression using equals (=) has components that are of different data types."

I am trying to subset my data with PROC SQL, and it is giving me an error when I use my variable TNM_CLIN_STAGE_GROUP. Example below:
PROC SQL;
create table subset as
select ncdb.*
from ncdb
where YEAR_OF_DIAGNOSIS>2002
AND SEX = 2
AND LATERALITY IN (1,2,3)
AND HISTOLOGY = 8500
AND TNM_CLIN_STAGE_GROUP = 1;
quit;
ERROR: Expression using equals (=) has components that are of different data types.
When I run the same code, but take out the variable TNM_CLIN_STAGE_GROUP, the code works. Anyone know what the problem with that variable's name is?
That error indicates a difference in type. SAS has only two types, numeric and character, so the variable is probably character; verify the specific values, but in general it likely needs quotations (single or double, doesn't matter in this case).
If it is not a hardcoded value, but a value of another variable, you can use PUT to convert to character or INPUT to convert to numeric, whichever is easier to convert based on the data.
SAS in a data step will happily convert this for you, but in SQL and SQL-like (WHERE statements) it does not automatically convert character to numeric and vice versa; you must provide the correct type.
Before doing equality, check what you are trying to compare.
Check the structure of you ncbd table, in particulary field type of TNM_CLIN_STAGE_GROUP
You would see the real type, if its a varchar, you need to use single quote like #JChao suggest in is comment.
If its another type, so you need to adapt the comparator or use cast if you don t have choice.

Code Generater interprets NUMERIC(20,0) as BIGDECIMAL while it should be interpreted as Long

I have a table with a field name "BID" with its data type set as NUMERIC(20,0). Now i know that it will never be a decimal/float value but always be a int/long i.e a natural number.
Is there a way for the code generator to make the variable inside the generated model class a Long as opposed to java.math.BigDecimal which it makes currently. Can it be set in jooq.properties??
This "feature" is currently only available for the Oracle database, where NUMBER is the only numeric type available. Using Oracle with jOOQ, NUMBER(20, 0) would map to java.math.BigInteger instead of java.math.BigDecimal.
This behaviour will also be available for other RDBMS in the next release 1.6.3. See
https://sourceforge.net/apps/trac/jooq/ticket/639
Besides that, overriding of data type mappings in the code generator is currently not possible, but you could use BIGINT as suggested by gbn, if you don't really need 20 decimal digits. BIGINT can hold most 19-digit decimals...