Inserting a polygon into MySQL - mysql

I have a MySQL 8 table with a column called "coordinates" of type "polygon".
I am trying to insert a set of coordinates into it, like so:
INSERT INTO contract (coordinates)
VALUES (POLYGON(
(34.786166422784426, 32.162676265661624),
(34.720248454034426, 32.01024096292725),
(34.816378825128176, 31.973162105505374),
(34.86993717473755, 32.1338371543335),
(34.786166422784426, 32.162676265661624))
)
which is giving me a "column count doesn't match value count at row 1" error.
Why is this? How do I properly format this query? And how can I explicitly pass an ESRI with it?
This, by the way, works fine:
INSERT INTO contract (coordinates, smart_contract_version_id)
VALUES (ST_GeomFromText('POLYGON(( 34.786166422784426 32.162676265661624 , 34.720248454034426 32.01024096292725 , 34.816378825128176 31.973162105505374 , 34.86993717473755 32.1338371543335 , 34.786166422784426 32.162676265661624 ))', 4326), 1)

You are inserting wrong .. You don't need the sets of parens .. Note double parens are INTENTIONAL .. AND the X / Y is denoted by a space .. Not a comma. If it works without the "double parens" It's because you don't have any insets -- "holes" etc ..
POLYGON((
34.786166422784426 32.162676265661624,
34.720248454034426 32.01024096292725,
34.816378825128176 31.973162105505374,
34.86993717473755 32.1338371543335,
34.786166422784426 32.162676265661624
))

Related

GAMS csv read issue

I'm trying to read a .csv file with the following format using MAC:
;lon;lat
0;55,245594;25,066697
1;55,135613;25,070419
2;55,275683;25,203425
What I am doing so far is:
$call csv2gdx coords.csv id=d index=1 values=2..lastCol useHeader=y
sets
i
c /x,y/
;
parameters
dloc(i,c) 'locations'
;
$gdxin clients_csv.gdx
$load ___ ?
What I want to do is read the lat,lon coordinates in the parameter dloc so as for each i to have a pair of coords c, i.e. lat, lon.
Example output:
x y
i1 17.175 84.327
Running your code produces an error from csv2gdx:
*** ErrNr = 15 Msg = Values(s) column number exceeds column count; Index = 2, ColCnt = 1
Per default, csv2gdx expects the entries separated by commas, which you do not have in your data. You could also define semicolon or tab as separator by means of an option, but if the data has really the format you posted, you do not need to call csv2gdx at all. You could just include the data directly like this:
Sets
i
c
;
Table dloc(i<,c<) 'locations'
$include coords.csv
;
Display dloc;
EDIT after change of input data format:
The error message is still the same. And also the reason is the same: You use a different field separator than the default one. If you switch that using the option fieldSep=semiColon, you will realize that also your decimal separator is non-default for csv2gdx. But this can be changed as well. Here is the whole code (with adjusted csv2gdx call and adjustments for data loading). Note that sets i and c get implicitly defined when loading dloc with the < syntax in the declaration of dloc.
$call csv2gdx coords.csv id=d index=1 values=2..lastCol useHeader=y fieldSep=semiColon decimalSep=comma
Sets
i
c
;
parameters
dloc(i<,c<) 'locations'
;
$gdxin coords.gdx
$load dloc=d
Display dloc;
$exit\

MYSQL: Validate Input with Regular Expressions REGEX

i have one question with regard to MYSQL. I want to create a function that is able to check whether an Input is given in a specific format.
The output should be in the following shape:
***x x (a) n (n) (n) (n)
with :
x = letters and numbers
n = numbers
a = letters
brackets = optional Values***
So my Solution until now is this (User 'Nick' helped me):
CREATE FUNCTION validate_number(testnumber VARCHAR(7))
RETURNS INT
DETERMINISTIC
RETURN testnumber REGEXP '^[[:alnum:]]{2}[[:alpha:]]?[[:digit:]]{1,4}$';
And this approach works for most cases.
But when i enter a value that exceeds the possible amount of elements (max elements = 7) i get no result.
example:
validate_number('00A00002345')
=> no result.
Do you guys have an idea what the problem is?
Thank you very much in advance.
you are actually pointing out the solution of the problem :)
just change VARCHAR(7) to something bigger VARCHAR(2000)
When I run your function, I get the error:
select validate_number('00A00002345')
Data too long for column 'testnumber' at row 1
You can add a length to the varchar.
CREATE FUNCTION validate_number (
in_testnumber VARCHAR(32000)
)
Or, use text:
CREATE FUNCTION validate_number (
in_testnumber text
)
RETURNS INT
DETERMINISTIC
BEGIN
RETURN (in_testnumber REGEXP '^[[:alnum:]]{2}[[:alpha:]]?[[:digit:]]{1,4}$');
END;

Querying json in postgres

I have to extract data from a json file who contains spatial information. The content of this file is
{"vertices":[{"lat":46.744628268759314,"lon":6.569952920654968},
{"lat":46.74441692818192,"lon":6.570487107359068},
{"lat":46.74426116111054,"lon":6.570355867853787},
{"lat":46.74447250168793,"lon":6.569821681149689}],
"name":"demo-field",
"cropType":"sugarbeet",
"cropPlantDistance":0.18000000715255737,
"rowDistance":0.5,"numberOfRows":[28,12,12],"seedingDate":"2016-08-17T07:39+00:00"}
I've created a table then copied the content of this file into it
create table field(data json);
COPY field(data) FROM '/home/guest-pc5/field.json';
I now I can query my data
SELECT json_array_elements(data->'vertices') from field;
{"lat":46.744628268759314,"lon":6.569952920654968}
{"lat":46.74441692818192,"lon":6.570487107359068}
{"lat":46.74426116111054,"lon":6.570355867853787}
{"lat":46.74447250168793,"lon":6.569821681149689}
(4 rows)
The problem is that I can't use it like that. I would like to catch only values of "lat" and "lon" to put them in the field table
I've tried to use the function json_to_recordset without success
select * from json_to_recordset('[{"lat":46.744628268759314,"lon":6.569952920654968},{"lat":46.74441692818192,"lon":6.570487107359068},{"lat":46.74426116111054,"lon":6.570355867853787},{"lat":46.74447250168793,"lon":6.569821681149689}]') as (lat numeric, lon numeric);
ERROR: function json_to_recordset(unknown) does not exist
LINE 1: select * from json_to_recordset('[{"lat":46.744628268759314,...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
You can use json manipulator operator ->> to get the value you want as text out of json_array_elements output. To make it easier, you can call json_array_elements in FROM clause (which is a lateral call to a set-returning function):
SELECT
f.data AS original_json,
CAST((e.element->>'lat') AS numeric) AS lat,
CAST((e.element->>'lon') AS numeric) AS lon
FROM
field AS f,
json_array_elements(f.data->'vertices') AS e(element);
With that, you can simple create a table (or use INSERT into an existent one):
CREATE TABLE coordinates AS
SELECT
f.data AS original_json,
CAST((e.element->>'lat') AS numeric) AS lat,
CAST((e.element->>'lon') AS numeric) AS lon
FROM
field AS f,
json_array_elements(f.data->'vertices') AS e(element);
OBS: The LATERAL there is implicit, as the LATERAL keyword is optional for set-returning function calls, but you could make it really explicit, as:
FROM
field f
CROSS JOIN LATERAL json_array_elements(f.data->'vertices') AS e(element);
Also, LATERAL is 9.3+ only, although you are certainly above that as you are using json_array_elements (also 9.3+ only).

Could anybody check my SQL code using SET, SELECT and CAST all at the same time

I'm trying to import some csv files into a table (on phpmyadmin). The problem is that the import wasn't really correct (the date wasn't showing, my values either (they showed correctly when the type was a VARCHAR) etc) so I thought about converting my values to the right type during my import. When I tried it for my date it worked using only the code below at the end :
SET Date = STR_TO_DATE (#dte, '%m.%d.%Y')
SQL;
But when I wanted to convert my values into a float or a decimal or whatever, it didn't work. It always says 'Syntax error or access violation' ( and I guess it starts from = ( Select CAST(#tot AS decimal(10,2)) etc ).
Do you have any suggestions please?
The request
Select CAST(#tot AS decimal(10,2))
from `bss_154`)
normally works on mySQL.
Thanks in advance.
PS: Here is my code :
$sql=<<<SQL
LOAD DATA INFILE '{$filename}'
IGNORE INTO TABLE nsui.bss_154
FIELDS TERMINATED BY ';'
ENCLOSED BY '"'
LINES TERMINATED BY '\r\n' IGNORE 1 LINES
(#dte, `BSC_Name`, `Segment_Name`, `SEGMENT`, `UP_QUAL`, `UP_LEVEL`,
`DOWN_QUAL`, `DOWN_LEV`, `DISTANCE`, `MSC_INVOC`, `INTFER_UP`,
`INTFER_DWN`, `UMBR`, `PBDGT`, `OMC`, `DIR_RETRY`, `PRE_EMPTION`,
`FIELD_DROP`, `LOW_DISTANCE`, `BAD_CI`, `GOOD_CI`, `HO_DUE_SLOW_MOV_MS`,
`HO_DUE_MS_SLOW_SPEED`, `HO_DUE_MS_HIGH_SPEED`,
`HO_ATT_DUE_SWITCH_CIRC_POOL`, `HO_ATT_DUE_ERFD`,
`HO_ATT_DUE_TO_BSC_CONTR_TRHO`, `HO_ATT_DUE_TO_DADLB`,
`HO_ATT_DUE_TO_GPRS`, `HO_ATT_DUE_TO_HSCSD`, `HO_ATT_DUE_BAD_SUPER_RXLEV`,
`HO_ATT_DUE_GOOD_REGULAR_RXLEV`, `HO_ATT_DUE_DIRECT_ACCESS`,
`HO_ATTEMPT_INTERBAND_DUE_LEVEL`, `HO_ATTEMPT_DUE_TO_ISHO`,
`HO_ATT_DUE_INTERSYS_DIRECT_ACC`, `HO_ATT_FOR_AMR_TO_HR`,
`HO_ATT_FOR_AMR_TO_FR`, `HO_ATT_INTER_BAND_SDCCH`,
`HO_ATT_INTER_BAND_TCH`, `HO_ATT_INTER_BTS_TYPE_SDCCH`,
`HO_ATT_INTER_BTS_TYPE_TCH`, #tot)
SET Date = STR_TO_DATE (#dte, '%m.%d.%Y'),
Hoattempts_outgoing_and_intra-cell = (
Select CAST(#tot AS decimal(10,2))
from `bss_154`)
SQL;
Also, perhaps you want to create the proper data types (VARCHAR) in the table definition first, then import the data that you can, and then create another script that imports and fixes the field data that's left over using the proper FORMAT and CAST statement syntaxes:
FORMAT ( value, format [, culture ] )
See: https://msdn.microsoft.com/en-us/library/hh213505.aspx
CAST ( expression AS data_type [ ( length ) ] )
See: https://msdn.microsoft.com/en-us/library/ms187928.aspx
With some code like:
CAST(FORMAT(#tot, 'N', 'en-us') as varchar) As SOME_TOTAL

number_format() with MySQL

hey i need a way to get a formated number from my column decimal(23,2) NOT NULL DEFAULT '0.00'
in php i could use this function number_format('1111.00', 2, ',', '.');
it would return 1.111,00 (in Germany we use , to define decimal numbers)
how would i do this in mysql? with string replaces?
http://blogs.mysql.com/peterg/2009/04/
In Mysql 6.1 you will be able to do FORMAT(X,D [,locale_name] )
As in
SELECT format(1234567,2,’de_DE’);
For now this ability does not exist, though you MAY be able to set your locale in your database my.ini check it out.
With performance penalty and if you need todo it only in SQL you can use the FORMAT function and 3 REPLACE :
After the format replace the . with another char for example #, then replace the , with a . and then the chararacter you choose by a , which lead you for your example to 1.111,00
SELECT REPLACE(REPLACE(REPLACE(FORMAT("1111.00", 2), ".", "#"), ",", "."), "#", ",")
You can use
SELECT round(123.4566,2) -> 123.46
FORMAT(X,D) Formats the number X to a format like '#,###,###.##', rounded to D decimal places, and returns the result as a string. If D is 0, the result has no decimal point or fractional part.
SELECT FORMAT(12332.123456, 4);
-> '12,332.1235'
Antonio's answer
CONCAT(REPLACE(FORMAT(number,0),',','.'),',',SUBSTRING_INDEX(FORMAT(number,2),'.',-1))
is wrong; it may produce incorrect results!
For example, if "number" is 12345.67, the resulting string would be:
'12.346,67'
instead of
'12.345,67'
because FORMAT(number,0) rounds "number" up if fractional part is greater or equal than 0.5 (as it is in my example)!
What you COULD use is
CONCAT(REPLACE(FORMAT(FLOOR(number),0),',','.'),',',SUBSTRING_INDEX(FORMAT(number,2),'.',-1))
if your MySQL/MariaDB's FORMAT doesn't support "locale_name" (see MindStalker's post - Thx 4 that, pal). Note the FLOOR function I've added.
At least as far back as MySQL 5.5 you can use format:
SELECT FORMAT(123456789.123456789,2);
/* produces 123,456,789.12 */
SELECT FORMAT(123456789.123456789,2,'de_DE');
/*
produces 123.456.789,12
note the swapped . and , for the de_DE locale (German-Germany)
*/
From the MySQL docs:
https://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_format
Available locales are listed elsewhere in the docs:
https://dev.mysql.com/doc/refman/5.5/en/locale-support.html
CREATE DEFINER=`yourfunctionname`#`%` FUNCTION `money`(
`betrag` DECIMAL(10,2)
)
RETURNS varchar(128) CHARSET latin1
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
return(
select replace(format(cast(betrag as char),2),',',"'") as betrag
)
will creating a MySql-Function with this Code:
select replace(format(cast(amount as char),2),',',"'") as amount_formated
You need this:
CONCAT(REPLACE(FORMAT(number,0),',','.'),',',SUBSTRING_INDEX(FORMAT(number,2),'.',-1))