MYSQL-how to insert geometry data - mysql

I'm trying to insert geometry data using MYSQL, here is a code-example:
CREATE TABLE CARTESIAN
(
ROW_ID INT NOT NULL,
G GEOMETRY,
PRIMARY KEY(ROW_ID)
)
INSERT INTO CARTESIAN
VALUES (0,'POINT(1 1)'),
(1,'LINESTRING(2 1, 6 6)'),
(2,'POLYGON((0 5, 2 5, 2 7, 0 7, 0 5))')
When I run the INSERT I receive the message "Cannot get geometry object from data you send to the GEOMETRY field".
Can you explain me where I'm wrong?

You need to convert the text representations into GEOMETRY before you can insert them using the ST_GeomFromText function. Try this:
CREATE TABLE CARTESIAN
(
ROW_ID INT NOT NULL,
G GEOMETRY,
PRIMARY KEY(ROW_ID)
);
INSERT INTO CARTESIAN
VALUES (0,ST_GeomFromText('POINT(1 1)')),
(1,ST_GeomFromText('LINESTRING(2 1, 6 6)')),
(2,ST_GeomFromText('POLYGON((0 5, 2 5, 2 7, 0 7, 0 5))'));
SELECT * FROM CARTESIAN
Output:
ROW_ID G
0 [GEOMETRY - 25 B]
1 [GEOMETRY - 45 B]
2 [GEOMETRY - 97 B]

Related

MySQL merge json field with new data while removing duplicates, where the json values are simple scalar values

Suppose that I have a MySQL table with a JSON field that contains only numbers, like this (note: using MySQL 8):
CREATE TABLE my_table (
id int,
some_field json
);
Sample data:
id: 1
some_field: [1, 2, 3, 4, 5]
id: 2
some_field: [3, 6, 7]
id: 3
some_field: null
I would like to merge another array of data with the existing values of some_field, while removing duplicates. I was hoping that this might work, but it didn't:
update my_table set some_field = JSON_MERGE([1, 2, 3], some_field)
The result of this would be:
id: 1
some_field: [1, 2, 3, 4, 5]
id: 2
some_field: [1, 2, 3, 6, 7]
id: 3
some_field: [1, 2, 3]
Considering you have 3 records in your table and you want to merge 1 and 2 as mentioned in your example.
I hope JavaScript is suitable to follow through for you.
// Get both the records
const records = db.execute(“SELECT id, some_field FROM my_table WHERE id=1 OR id=2”);
// You get both the rows.
// Merging row1, you can either use the Set data structure if you’re dealing with numbers like your example, or you could loop using a map and use the spread operator if using JSON. Since your object is an array, I’ll just be explaining to merge 2 arrays.
records[0].some_field = Array.from(new Set(records[0].some_field + record[1].some_field))
// Same for second record.
records[1].some_field = Array.from(new Set(records[0].some_field + record[1].some_field))
// Now update both the records in the database one by one.

PIvoting table around date column in Mysql

I am trying to pivot this table
timetableId, assignmentId, dateChecked, hoursWorked
1, 11, 2017-09-10, 5
2, 12, 2017-09-10, 5
3, 13, 2017-09-11, 8
4, 11, 2017-09-11, 8
5, 12, 2017-09-11, 8
6, 13, 2017-09-10, 8
so that it would show
assignmentId, tenth, eleventh
11, 5, 8
12, 5, 8
13, 0, 8
I have the following code based on the tutorial from this website http://stratosprovatopoulos.com/web-development/mysql/pivot-a-table-in-mysql/
create view timetable_extended as (
select
timetables.assignmentId,
case when dateChecked = '10-09-2017' then timetables.hoursWorked end as tenth,
case when dateChecked = '11-09-2017' then timetables.hoursWorked end as eleventh
from timetables
);
create view timetable_extended_Pivot as (
select
assignmentId,
sum(tenth) as tenth,
sum(eleventh) as eleventh
from timetable_extended
group by assignmentId
);
create view timetable_extended_Pivot_Pretty as (
select
assignmentId,
coalesce(tenth, 0) as tenth,
coalesce(eleventh, 0) as eleventh
from timetable_extended_Pivot
);
however for some reason the first view returns all values as null instead of doing what it is supposed to do - namely this
assignmentId, tenth, eleventh
11, 5, NULL
11, NULL 8
12, 5, NULL
12, NULL 8
13, NULL, 8
What am I doing wrong? Do I need to convert the date to a string?
I have tried the same code with string as the main column and it works perfectly
create table User_Items
(
Cust_Names varchar(10),
Item_Type varchar(50),
Item_Amount float
);
insert into User_Items values
('Alison', 'Computer', 345.39),
('Alison', 'Monitor', 123.45),
('Jason', 'Computer', 435.34),
('Jason', 'Monitor', 158.23),
('Jason', 'Software', 243.54);
create view User_Items_Extended as (
select
User_Items.Cust_Names,
case when Item_Type = "Computer" then Item_Amount end as Computer,
case when Item_Type = "Monitor" then Item_Amount end as Monitor,
case when Item_Type = "Software" then Item_Amount end as Software
from User_Items
);
create view User_Items_Extended_Pivot as (
select
Cust_Names,
sum(Computer) as Computer,
sum(Monitor) as Monitor,
sum(Software) as Software
from User_Items_Extended
group by Cust_Names
);
create view User_Items_Extended_Pivot_Pretty as (
select
Cust_Names,
coalesce(Computer, 0) as Computer,
coalesce(Monitor, 0) as Monitor,
coalesce(Software, 0) as Software
from User_Items_Extended_Pivot
);
The problem is here:
case when dateChecked = '10-09-2017'
Use YYYY-MM-DD format for your date comparisons, not MM-DD-YYYY.

query json array with Oracle 12cR2 json features

I am using Oracle (12cR2) json but couldn't find a way to query arrays containing certain elements. Here is the test code:
CREATE TABLE json_array (
id NUMBER NOT NULL,
array CLOB,
CONSTRAINT json_array_pk PRIMARY KEY (id),
CONSTRAINT json_array_chk_1 CHECK (array IS JSON)
);
INSERT INTO json_array (id, array) VALUES (1, '{"a":[1, 3]}');
INSERT INTO json_array (id, array) VALUES (2, '{"a":[2, 4, 6]}');
INSERT INTO json_array (id, array) VALUES (3, '{"a":[1, 2, 5]}');
INSERT INTO json_array (id, array) VALUES (4, '{"a":[2, 5]}');
INSERT INTO json_array (id, array) VALUES (5, '{"a":[5]}');
INSERT INTO json_array (id, array) VALUES (6, '{"a":[5, 2]}');
COMMIT;
Create a domain index:
CREATE SEARCH INDEX idx_json_array ON json_array (array) FOR JSON;
I want to find all rows containing the array element 2 and 5, regardless their order in the array, i.e. the SQL should return the rows with id 3, 4, 6.
I tried many options:
SQL1:
select * from json_array j -- return any arrays containing 2
where json_exists(j.array, '$?(#.a[0] == 2)');
==> return the rows containing 2: id = 2, 3, 4, 6
SQL2:
select * from json_array j -- return arrays containing 2 at index 1
where json_exists(j.array, '$?(#.a[0] == 2 || #.a[0] == 5)');
==> return rows containing 2 or 5: id = 2, 4, 5, 6
SQL3:
select * from json_array j -- return arrays containing 2 at index 1
where json_exists(j.array, '$?(#.a[0] == 2 && #.a[0] == 5)');
==> return no row
SQL4:
select * from json_array j -- returns arrays containing 2 OR 5
where json_textcontains(j.array, '$.a', '[2,5]');
==> return rows containing 2 or 5: id = 2, 3, 4, 5, 6
SQL5:
select * from json_array j
where json_textcontains(j.array, '$.a', '{[2] & [5]}');
==> returns rows containing 2 AND 5, with 2 preceding 5
The only SQL that returns what I want is:
SQL6:
select * from json_array j
where json_textcontains(j.array, '$.a', '[2]') AND json_textcontains(j.array, '$.a', '[5]');
==> returns id = 3, 4, 6
But this solution can be very cumbersome when the number of elements increases.
Question: are there better option that SQL6 to return the same results?
Oracle version for testing 12c R2
Thanks in advance
James
Does this help...
SQL> with MY_TABLE as
2 (
3 select 1 as ID, '{"a":[1, 3]}' as ARRAY
4 from DUAL
5 union all
6 select 2 as ID, '{"a":[2, 4, 6]}' as ARRAY
7 from DUAL
8 union all
9 select 3 as ID, '{"a":[1, 2, 5]}' as ARRAY
10 from DUAL
11 union all
12 select 4 as ID, '{"a":[2, 5]}' as ARRAY
13 from DUAL
14 union all
15 select 5 as ID, '{"a":[5]}' as ARRAY
16 from DUAL
17 union all
18 select 6 as ID, '{"a":[5, 2]}' as ARRAY
19 from DUAL
20 )
21 select ID
22 from MY_TABLE
23 where json_exists(ARRAY,'$?(#.a == 2 && #.a == 5)')
24 /
ID
----------
3
4
6
SQL>

SQL - How to join foreign keyed data, with the column names of the parent table

I have two tables:
RUNS
ID numb bay0 bay1 bay2
-----------------------------
1 55 aa bb cc
2 66 gg NULL dd
3 77 dd bb NULL
DATA
ID run_id serial data
------------------------------
1 2 gg xx
2 2 dd xx
DATA.run_id is a foreign key pointing to RUNS.ID.
'serial' and the value of 'bay%' are foreign keys pointing to another table 'products'.
What I would like is an output like this:
OUTPUT
ID run_id serial data bay
------------------------------
1 2 gg xx bay0
2 2 dd xx bay2
Such that the column headers of the first table are put into the output rows of the second tables data.
I have been playing around with alot of queries to get this to work like getting the column headers:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'a'
AND TABLE_SCHEMA = 'b'
AND COLUMN_NAME LIKE 'bay%'
But ultimately I can't see how I am going to get/merge/concatenate this output. Can someone help me?
Thanks
If number of columns is fixed you can do this:
SELECT
data.id, data.run_id, data.serial, data.data,
CASE data.serial
WHEN runs.bay0 THEN 'bay0'
WHEN runs.bay1 THEN 'bay1'
WHEN runs.bay2 THEN 'bay2'
ELSE NULL
END AS bay
FROM
data
JOIN runs ON (data.run_id = runs.id)
Just list all possible variants in CASE statement. Not elegant, but will work until you add/remove bayX column to data table.
DECLARE #Table1 TABLE
( ID int, run_id int, serial varchar(2), data varchar(2))
;
INSERT INTO #Table1
( ID , run_id , serial , data )
VALUES
(1, 2, 'gg', 'xx'),
(2, 2, 'dd', 'xx')
;
DECLARE #Table2 TABLE
( ID int, serial int, bay0 varchar(2), bay1 varchar(2), bay2 varchar(2))
;
INSERT INTO #Table2
( ID , serial , bay0 , bay1 ,bay2)
VALUES
(1, 55, 'aa', 'bb','cc'),
(2, 66, 'gg', NULL,'dd')
;
SELECT T.ID,T.run_id,T.serial,T.DATA,tt.COL FROM #Table1 t
INNER JOIN
(
SELECT COL,VAL FROM #Table2
cross apply (values('bay0',bay0),('bay1',bay1),('bay2',bay2))cs(COL,VAL)
WHERE col <> 'BAY1')tt
on T.serial = TT.VAL

SQL Server Tree Query

I need some help is MS SQL Server Query. I’m not much of a DBA. I have an application with an Organization Table which is made up of a parent-child relationship:
CREATE TABLE [dbo].[Organizations](
[OrgPK] [int] IDENTITY(1,1) NOT NULL,
[OrgParentFK] [int] NULL,
[OrgName] [varchar](200) NOT NULL,
CONSTRAINT [PK__Organizations] PRIMARY KEY CLUSTERED
Sample data looks like this:
OrgPK, OrgParentFK, OrgName
1, 0, Corporate
2, 1, Department A
3, 1, Department B
4, 2, Division 1
5, 2, Division 2
6, 3, Division 1
7, 6, Section 1
8, 6, Section 2
I'm trying to generate a query that returns an org path based on a given OrgPK. Example if given OrgPK = 7 the query would return 'Corporation/Department B/Division 1/Section 1'
If give OrgPk = 5 the return string would be 'Corporation/Department A/Division 2'
Thank you for your assistance.
WITH OrganizationsH (OrgParentFK, OrgPK, OrgName, level, Label) AS
(
SELECT OrgParentFK, OrgPK, OrgName, 0, CAST(OrgName AS VARCHAR(MAX)) As Label
FROM Organizations
WHERE OrgParentFK IS NULL
UNION ALL
SELECT o.OrgParentFK, o.OrgPK, o.OrgName, level + 1, CAST(h.Label + '/' + o.OrgName VARCHAR(MAX)) As Label
FROM Organizations o JOIN OrganizationsH h ON o.OrgParentFK = h.OrgPK
)
SELECT OrgParentFK, OrgPK, OrgName, level, Label
FROM OrganizationsH
WHERE OrgPK = 5
h/t to marc_s
It can also be solved by creating a scalar valued function:
-- SELECT [dbo].[ListTree](5)
CREATE FUNCTION [dbo].[ListTree](#OrgPK int)
RETURNS varchar(max)
AS
BEGIN
declare #Tree varchar(MAX)
set #Tree = ''
while(exists(select * from dbo.Organizations where OrgPK=#OrgPK))
begin
select #Tree=OrgName+'/'+#Tree,
#OrgPK=OrgParentFK
from dbo.Organizations
where OrgPK=#OrgPK
end
return left(#Tree,len(#Tree)-1)
END