How to get the area of a polygon explicitly written? - oracle

I'm trying to get the area of explicitly written polygon without any success.
SELECT SDO.GEOM.SDO_AREA('POLYGON ((...))')
... contains my polygon values
I'm getting error:
SQL Error [923] [42000]: ORA-00923: FROM keyword not found where expected
How can I write my polygon in the select query and get the area of this polygon ?

It is SDO_GEOM.SDO_AREA and not SDO.GEOM.SDO_AREA.
You need to pass a SDO_GEOMETRY object as the first argument and not a string (containing a GIS shape).
You need a second argument containing the tolerance (or a SDO_DIM_ARRAY).
You need a FROM clause and a table to select from (DUAL is usually used if you only want a single row).
You need to pass a valid GIS shape; ... is not valid.
Like this:
SELECT SDO_GEOM.SDO_AREA(
SDO_GEOMETRY('POLYGON ((0 0, 0 1, 1 1, 1 0))'),
0.0000000005
)
FROM DUAL;
db<>fiddle here

Related

Most common "denominators" in a two column list in Google Sheets

How can I find the most commonly found 'Code' (Col B) associated with each unique 'Name' in (Col A) and find the closest value if the 'Code' in Col B is unique?
The image below shows the shared google sheet with Starting data in Columns A & B and the desired output columns in columns C and D. Each Unique Name has associated codes. Column D displays the most commonly occuring Code for each unique name. For example, Buick La Sabre 1 has 3 associated codes in B3,B4,B5 but in D3 only 98761 because it appears more frequently than the other 2 codes do in B2:B. I will explain what I mean by the closest value below.
The Codes that have a count = 1 are unique so the output in column D tries to find the closest match.
However, when the count of the code in B2:B > 1, then the output in column D = to the most frequent code associated with the Name.
Approach when there is 2 or more of the same values in column B
Query
I thought I might use a QUERY with a ORDER BY count(B) DESC LIMIT 2 in a fashion similar to this working equation:
QUERY($A$1:$D$25,"SELECT A, B ORDER BY B DESC Limit 2",1)
but I could not get it to work when I substituted in the Count function.
SORT & INDEX OR VLOOKUP
If the query function can't be fixed to work, then I thought another approach might be to combine a Vlookup/Index after sorting column B in a descending order.
UNIQUE(sort($B$3:$B,if(len($B$3:$B),countif($B$3:$B,$B$3:$B),),0,1,1))
Since a Vlookup or Index using multiple criteria would just pull the first value it finds, you would just end up with the first matching value, we would then get the most frequent value.
Approach when there is < 2 of the same values in column B
This is a little more complicated since the values can be numbers and letters.
A solution like that seen in the image below could be used if everything were a number. In our case there will usually be between 3 - 5 character alphanumeric code starting with 0 - 1 letters numbers and followed by numbers. I'm not sure what the best way to match a code like A1234 would be. I imagine a solution might be to SPLIT off letters and trying to match those first. For example A1234 would be split into A | 1234, then matching the closest letter and then the closest number. But I really am not sure what the best solution to this might be that works within the constraints of Google Sheets.
In the event that a number is equidistant between two numbers, the lower number should be chosen. For example, if 8 is the number and the closest match would be 6 or 10, then 6 should be selected.
In the event that a letter is being used it should work in a similar fashion. For example, thinking of {A, B, C} as {1, 2, 3}, B should preferrentially match to A since it comes before C.
In summary, looking for a way to find the most frequently associated code in col B that is associated with unique names in col A in this sheet and; In the event where there are none of the same codes in B2:B, a formula that will find the closest match for a number or alphanumeric code.
You can use this formula:
=QUERY({range of numerators & denominators}, "select Col2, count(Col2) group by Col2 label Col2 'Denominator', count(Col2) 'Count'")
That outputs something like this:
Denominator
Count
Den 1
Count 1
Den 2
Count 2
use:
=ARRAY_CONSTRAIN(SORTN(QUERY({A3:B},
"select Col1,Col2,count(Col2)
where Col1 is not null
group by Col1,Col2
order by count(Col2) desc,Col2 asc
label count(Col2)''"), 9^9, 2, 1, 1), 9^9, 2)

Query() function in Google Sheets yields stray value: Why, and how can I fix it?

I would like to run a query statement that adds a bullet (●) to each row of output.
Here is my sample data:
Here is the query:
=query($A$1:$B$3,"SELECT '●',A,B",0)
Here is the result:
Why does the first stray line appear in the output ["●"()], and how can I write the query so that it yields only rows 2, 3, 4 and not the first row?
Note that the actual data is much more complicated than this, so solving it with a filter or array does not work well. I need a query solution. And I'd really like to know why that first line is appearing in the first place.
Thanks for the help.
KLS
=QUERY($A$1:$B$3, "SELECT '●', A, B LABEL '●' ''", 0)
This assigns an empty string to the label for that column, thus eliminating the label row.

Inferring type of values returned by the SQLite3 shell tool

I am out of necessity using the SQLite3 shell tool to maintain a small database. I'm using -header -ascii flags, although this applies—as far as I can tell—to any of the output choices. I'm looking a way to avoid ambiguity over the type of any one value returned. Consider the following:
Create Table `things` (`number` Integer, `string` Text, `binary` Blob);
Insert Into `things` (`number`,`string`,`binary`) Values (4,'4',X'34');
Select * From `things`;
This returns (using caret notation):
number^_string^_binary^^4^_4^_4^^
As is evident, there is no way to infer the type of any of the '4' characters from the response alone as none of them have distinguishing delimiters.
Is there any way to coerce the inclusion of type metadata into the response?
I'd like to avoid:
Altering query statements to also include types as that would be obfuscatory and would be superfluous in the event I did switch interfaces;
Prefixing TEXT and BLOB values prior to insert as this would have to be uniform for all TEXT and BLOB interaction (in saying that, this is still my preferred choice should it come to that).
What I'm looking for is a switch of some kind that indicates type as part of SQLite's response, e.g.:
number^_string^_binary^^4^_'4'^_X'4'^^
number^_string^_binary^^4^_text:4'^blob:4^^
Or some variation thereof. Fundamental to this is the response alone contains enough information to discern the type and value of each element of that response (much in the same way sqlite3_column_type() allows in the SQLite Library API).
Update: I've refined this question since the first answer by #mike-sherrill-cat-recall to clarify expectations.
In SQLite, it doesn't always make sense to echo the data type of a column. SQLite doesn't have column-wise data types in the traditional sense. You can use typeof(X) in SQL to show the "datatype of the expression X".
sqlite> create table test (n integer, d decimal(8, 2));
sqlite> insert into test (n, d) values (8, 3.14);
sqlite> insert into test (n, d) values ('wibble', 'wibble');
Inserting text into an integer column succeeds.
sqlite> select n, typeof(n), d, typeof(d) from test;
n typeof(n) d typeof(d)
---------- ---------- ---------- ----------
8 integer 3.14 real
wibble text wibble text
You can concatenate anything you like--even producing caret notation--but it's kind of clumsy.
sqlite> select '(' || typeof(n) || ')^_' || n as caret_n from test;
caret_n
-------------------------
(integer)^_8
(text)^_wibble
SQLite Core Functions
The shell always converts printed values to strings. (That's what "print" means.)
If you don't want to add separate output columns for the types, you could use the quote function to output all values according to SQL syntax rules:
sqlite> with v(x) as (values (null), (1), (2.3), ('hello'), (x'00')) select quote(x) from v;
NULL
1
2.3
'hello'
X'00'

How to use checkbox values in code?

In my Oracle APEX application page I have checkbox item with multiple values. The source of checkbox is like this:
STATIC:One,Two,Apple
In page process I need to use the value from checkbox in PL/SQL code. As far as I understand I get colon separated values. Question is how to use those values and test if Value is One, then do this. If Two is checked as well, then do something more.
Depending on situation you can use:
Convert string with delimiter to table (you can use this as subquery):
select regexp_substr('1:2:3','[^:]+', 1, level) ID from dual
connect by regexp_substr('1:2:3', '[^:]+', 1, level) is not null;
ID
--
1
2
3
Check one value using instr:
where instr('1:2:3', '2') > 0
If value of the second argument of the function is contained inside the first argument - function returns its position, otherwise - 0.
For performance I prefer the INSTR function, e.g. INSTR(':'||:p_item||':',':Two:') > 0

DataColumn Expression Divide By Zero

I'm using basic .net DataColumns and the associated Expression property.
I have an application which lets users define which columns to select from a database table. They can also add other columns which perform expressions on the data columns resulting in a custom grid of information.
The problem I have is when they have a calculation column along the lines of "(C2/C3)*100" where C2 and C3 are data columns and the value for C3 is zero. The old "divide by zero" issue.
The simple answer would be to convert the expression to "IIF(C3 = 0, 0, (C2/C3)*100)", however we don't expect the user to know to do that and at compile time I don't know what columns are defined. So I would have to programmatically determine which columns are being used in a division in order to construct the IIF clause. That could get quite tricky.
Is there another way to not throw an error and replace the result with 0 if a "Divide By Zero" error occurs?
Ok, I found a way. The key is to use Double and not Decimal for the column type, e.g. in the example above C3 should be a Double. This will result in a result of Infinity instead, which can be evaluated against using the expression as a whole.
E.g.
IIF(CONVERT(([C4] / [C3] )*100, 'System.String') = 'NaN' OR CONVERT(([C4] / [C3] )*100, 'System.String') = 'Infinity' OR CONVERT(([C4] / [C3] )*100, 'System.String') = '-Infinity', 0, ([C4] / [C3] )*100)
Decimal it seems doesn't provide that Infinity option.

Resources