Invalid WKT from ST_GeometryFromText(x) - sql

I'm trying to convert varchar WKT format to geometry using presto function ST_GeometryFromText but I get this error
Error running query: Invalid WKT: 0101000020E6100000000000407BF43E40000000203CFA3D40
The point format in the database is stored in this format 0101000020E6100000000000407BF43E40000000203CFA3D40 as varchar, i just want to convert it to a geometry point, i used to use ST_X & ST_Y in postgis but after migrating to presto these two functions aren't supported.

If you run
SELECT ST_AsText('0101000020E6100000000000407BF43E40000000203CFA3D40')
...in postgis, you will get the point POINT(30.955005645752 29.9774799346924).
If you want to separate longitude and latitude, run:
SELECT ST_X(ST_AsText('0101000020E6100000000000407BF43E40000000203CFA3D40')), ST_Y(ST_AsText('0101000020E6100000000000407BF43E40000000203CFA3D40'))

I found the answer is simply by removing this part of the string '20E61000', once removed, the function works fine, I've used this function
ST_GEOMFROMBINARY(FROM_HEX(REPLACE('0101000020E6100000000000407BF43E40000000203CFA3D40', '20E61000')))
and it worked fine, also I've verified the answer using python Shapley wkb function.

I had the same issue...had to massage the heck out of this thing.
select ST_GeomFromBinary(from_hex(to_utf8(replace(geom,'20E61000')))) as geom from ...

Related

Databricks Sql: Alternative to NCHAR() to replace characters

I have names in my table for which I need to replace certain characters with others.
I have the following code, but I get an error
REPLACE(REPLACE(TRIM(name),NCHAR(0x2019),NCHAR(0x0027)),NCHAR(0x200B),'')
However I get the following error message. Can somebody help me rewrite the code not using the Nchar function?
Undefined function: 'NCHAR'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'
Instead of NCHAR function you can use unicode literals (\uXXXX) to represent a character as it's described in Spark documentation, in your case it will be:
REPLACE(REPLACE(TRIM(name),'\u2019','\u0027'),'\u200B','')

SQLite Time Format Issues on Data Imported from a csv. A Number of Trailing Zeros

I was trying to query the duration of a WWE wrestler in the matches which he won and here I have successfully retrieved the data:
I would like to remove those zeros and I tried the following piece of code:
strftime(%H:%M:%S, R1.time_in_match)
which doesn't work and give the following error:
': near "%": syntax error
The data I imported were from a data frame which stores the time as time object and put them into the database as type DATETIME. The typeof function used on the "time_in_match" field returned type TEXT.
I was wondering if there is any way to format the time.
Thanks!
SQLite provides 2 functions for this case:
strftime('%H:%M:%S', R1.time_in_match)
and simpler:
time(R1.time_in_match)
because:
The time() function returns the time as HH:MM:SS
(from Date And Time Functions)
See the demo.
Your expression works as intended if you surround the format specifier with single quotes:
strftime('%H:%M:%S', time_in_match)
You could also just use string functions here:
substr(time_in_match, 1, 8)
Demo on DB Fiddle

ERROR: function regexp_matches(jsonb, unknown) does not exist in Tableau but works elsewhere

I have a column called "Bakery Activity" whose values are all JSONs that look like this:
{"flavors": [
{"d4js95-1cc5-4asn-asb48-1a781aa83": "chocolate"},
{"dc45n-jnsa9i-83ysg-81d4d7fae": "peanutButter"}],
"degreesToCook": 375,
"ingredients": {
"d4js95-1cc5-4asn-asb48-1a781aa83": [
"1nemw49-b9s88e-4750-bty0-bei8smr1eb",
"98h9nd8-3mo3-baef-2fe682n48d29"]
},
"numOfPiesBaked": 1,
"numberOfSlicesCreated": 6
}
I'm trying to extract the number of pies baked with a regex function in Tableau. Specifically, this one:
REGEXP_EXTRACT([Bakery Activity], '"numOfPiesBaked":"?([^\n,}]*)')
However, when I try to throw this calculated field into my text table, I get an error saying:
ERROR: function regexp_matches(jsonb, unknown) does not exist;
Error while executing the query
Worth noting is that my data source is PostgreSQL, which Tableau regex functions support; not all of my entries have numOfPiesBaked in them; when I run this in a simulator I get the correct extraction (actually, I get "numOfPiesBaked": 1" but removing the field name is a problem for another time).
What might be causing this error?
In short: Wrong data type, wrong function, wrong approach.
REGEXP_EXTRACT is obviously an abstraction layer of your client (Tableau), which is translated to regexp_matches() for Postgres. But that function expects text input. Since there is no assignment cast for jsonb -> text (for good reasons) you have to add an explicit cast to make it work, like:
SELECT regexp_matches("Bakery Activity"::text, '"numOfPiesBaked":"?([^\n,}]*)')
(The second argument can be an untyped string literal, Postgres function type resolution can defer the suitable data type text.)
Modern versions of Postgres also have regexp_match() returning a single row (unlike regexp_matches), which would seem like the better translation.
But regular expressions are the wrong approach to begin with.
Use the simple json/jsonb operator ->>:
SELECT "Bakery Activity"->>'numOfPiesBaked';
Returns '1' in your example.
If you know the value to be a valid integer, you can cast it right away:
SELECT ("Bakery Activity"->>'numOfPiesBaked')::int;
I found an easier way to handle JSONB data in Tableau.
Firstly, make a calculated field from the JSONB field and convert the field to a string by using str([FIELD_name]) command.
Then, on the calculated field, make another calculated field and use function:
REGEXP_EXTRACT([String_Field_Name], '"Key_to_be_extracted":"?([^\n,}]*)')
The required key-value pair will form the second caluculated field.

What to try to get BigQuery to CAST BYTES to STRING?

BigQuery Standard SQL documentation suggests that BYTE fields can be coerced into STRINGS.
We have a byte field that is the result of SHA256 hashing a field using BigQuery itself.
We now want to coerce it to a STRING, yet when we run "CAST(field_name to STRING)" we get an error:
Query Failed Error: Invalid cast of bytes to UTF8 string
What is preventing us from getting a string from this byte field? Is it surmountable? If so, what is the solution?
Below example should show you an idea
#standardSQL
WITH t AS (
SELECT SHA256('abc') x
)
SELECT x, TO_BASE64(x)
FROM t
in short - you can use TO_BASE64() for this
If you want to see the "traditional" representation of the hash in String, you have to use TO_HEX() function.
WITH table AS (
SELECT SHA256('abc') as bytes_field
)
SELECT bytes_field, TO_HEX(bytes_field) as string_field
FROM table
By default in the UI, BigQuery shows you the base64 representation but if you want to compare it with other sha256 function from other language, for example, you have to use TO_HEX()
You can try SAFE_CONVERT_BYTES_TO_STRING() function.
reference: SAFE_CONVERT_BYTES_TO_STRING

How to cast latitude, longitude coordinates as postgres geography type

My table has two float columns for latitude and longitude coordinates.
I want to use PostGIS's ST_DWithin to find all records which are within a certain distance from a given point.
The signature of ST_DWithin expects the first two parameters to be geometry or geography datatypes so I'm pretty sure the solution is to cast the lat/lng coordinates as geography, but I can't get it to work.
Here's what doesn't work:
SELECT *
FROM stops
WHERE ST_DWithin( ST_GeogFromText('SRID=4326;POINT(-77.09 38.89)'),
ST_GeogFromText('SRID=4326;POINT(' || stops.lng || ' ' || stops.lat || ')'), 10000.0)
I get this error:
ERROR: function st_geogfromtext(unknown) does not exist
LINE 1: SELECT * FROM stops WHERE ST_DWithin( ST_GeogFromText('SRID=...
What am I doing wrong?
Woops.
Turns out the original syntax (above) was actually correct. But I missed a key step afer installing PostGIS:
psql -d <DATABASE_NAME_HERE> -c "CREATE EXTENSION postgis";
Turns out you have to enable it on each database for it to work. This is why the function was unrecognized.
As there aren't many resources out there for this, I'm going to leave the question in case it proves useful to others.
An example in Gilbert Le Blanc's link seems to contain a method for casting during a function call:
SELECT ST_Distance('LINESTRING(-122.33 47.606, 0.0 51.5)'::geography,
'POINT(-21.96 64.15)':: geography);
Can you adapt that to your use case?