Transfer polygon information to point later using STContains() - sql-server

I would like to build a query that will transfer information from a polygon layer (~1100 records) to a point layer (~300 points). I want Comp_Numb and Stand_Number values to be transferred to the points layer when a new point is added to the database.
I have built the following query (it is a select query but I will change it to an update query when it is working properly):
SELECT GPS.Invent_Plot_ID, stands.Comp_Numb, stands.Stand_Number
FROM FORESTRY.dbo.[GSCA #] AS stands
INNER JOIN GPS_DATA.dbo.GPS_Forest_Inventory_test AS GPS
ON stands.Geometry.STContains(stands.Geometry) = 1
When I run the query it returns >590,000 records. I have looked around at examples such as this.
Where do I go next?

Related

Delphi, code example code getting list of overlapping polygons with SQL Server Spatial

The overlap between polygons can be evaluated using SQL Server spatial .STContains function (https://learn.microsoft.com/en-us/sql/t-sql/spatial-geometry/stcontains-geometry-data-type?view=sql-server-ver16&viewFallbackFrom=sql-server-ver18)
Can I get some code sample to get the list of polygons located inside a given polygon (the record index should be the query parameter), return a list of records inside this polygon?
select *
from table
where PolygonsInside (RecordIndex = 1)
How to get to this SQL query?
Your description ("overlap between polygons") doesn't necessarily match the function you've chosen (from the same documentation you've linked to, STContains() "Returns 1 if a geometry instance completely contains another geometry instance.".); STIntersects() may be a better choice.
Regardless of any of that, here's a query you'd write to find any polygon from a table that overlaps given the ID of another polygon in the same table.
select overlaps.ID, overlaps.Polygon
from PolygonTable as given
join PolygonTable as other
on other.Polygon.STIntersects(given.Polygon) = 1
and other.ID <> given.ID
where given.ID = 1;
That is, if you provide an ID of 1, that query will find any polygon in the table that intersects with that. Note, I've added a predicate in the join so as not to also return the polygon that has the ID provided - that may or may not be what you want but it's easily removed if you do want to return that one.

Send json from Stream analytics to Power Bi

I am trying to send simulated data from kepware to azure Hub and then to Stream analytic. Next step would be directly to Power Bi but it seems like stream analytics is sending an array to Power Bi.
here is my data from kepware:
SELECT
event.[values].id as id,
event.[values].v as Measurements,
event.[values].t as Time,
event.[values].q as Quality
INTO PowerBiVisualizationOutput
FROM PowerBiVisualizationInput AS event
CROSS APPLY GetArrayElements(event.[values]) AS sensordata
I have tried so many different way of writing quarries but they all are giving me null in output. Can some one please help me
Regards
The syntax for using GetArrayElements is illustrated here.
Note how it returns a record/object for each item/row of your array, that in your case you named sensordata (it's not event. anymore). That record has 2 properties : ArrayIndex and ArrayValue, that are hardcoded (part of GetArrayElements). Here you want to grab your properties out of ArrayValue:
SELECT
sensordata.ArrayValue.id as id,
sensordata.ArrayValue.v as Measurements,
sensordata.ArrayValue.t as Time,
sensordata.ArrayValue.q as Quality
INTO PowerBiVisualizationOutput
FROM PowerBiVisualizationInput AS event
CROSS APPLY GetArrayElements(event.[values]) AS sensordata
Edit following our conversation in comments:
Looking at the first screenshot, the field name we're trying to unfold is [value] and not value, the square brackets [] are in there.
To reference such fields in a query, we can use double quotes: "[value]":
SELECT
sensordata.ArrayValue.id as id,
sensordata.ArrayValue.v as Measurements,
sensordata.ArrayValue.t as Time,
sensordata.ArrayValue.q as Quality
INTO PowerBiVisualizationOutput
FROM PowerBiVisualizationInput AS event
CROSS APPLY GetArrayElements("[values]") AS sensordata

Query Performance in Access 2007 - drawing on a SQL Server Express backend

I've been banging my head on this issue for a little while now, and decided I should ask for help. I have a table which holds temperature/humidity chart recorder data (currently over 775,000 records) from which I am trying to run a statistical query against it. The problem is that this often will take up to two minutes, and sometimes will not come back at all - causing me to force close the program (Control-Alt-Delete). At first, I didn't have as much of a problem - it was only after I hit the magical 500k records mark that I started getting serious slowdowns, getting progressively worse as more data was compiled and imported into the table.
Here is the query (pass-through):
SELECT dbo.tblRecorderLogs.strAreaAssigned, Min(dbo.tblRecorderLogs.datDateRecorded) AS FirstRecorderDate, Max(dbo.tblRecorderLogs.datDateRecorded) AS LastRecordedDate,
Round(Avg(dbo.tblRecorderLogs.intTempCelsius),2) AS AverageTempC,
Round(Avg(dbo.tblRecorderLogs.intRHRecorded),2) AS AverageRH,
Count(dbo.tblRecorderLogs.strAreaAssigned) AS Records
FROM dbo.tblRecorderLogs
GROUP BY dbo.tblRecorderLogs.strAreaAssigned
ORDER BY dbo.tblRecorderLogs.strAreaAssigned;
Here is the table structure in which the chart data is stored:
idRecorderDataID Number Primary Key
datDateEntered Date/Time (indexed, duplicates OK)
datTimeEntered Date/Time
intTempCelcius Number
intDewPointCelcius Number
intWetBulbCelcius Number
intMixingGPP Number
intRHRecorded Number
strAssetRecorder Text (indexed, duplicates OK)
strAreaAssigned Text (indexed, duplicates OK)
I am trying to write a program which will allow people to pull data from this table based on Area Assigned, as well as start and end dates. With the dataset size I currently have, this kind of report is simply too much for it to handle (it seems) and the machine doesn't ever return an answer. I've had to extend the ODBC timeout to almost 180 seconds in any queries dealing with this table, simply because of the size. I could use some serious help, if people have some. Thank you in advance!
-- Edited 08/13/2012 # 1050 hours --
I have not been able to test the query on the SQL Server due to the fact that the IT department has taken control of the machine in question, and has someone logged into it full-time using the remote management console. I have tried an interim step to lessen the impact of the performance issue, but I am still looking for a permanent solution to this issue.
Interim step:
I created a local table mirroring the structure of the dbo.tblRecorderLogs SQL Server table, to which I do a INSERT INTO using the former SELECT statement as it's subquery. Then any subsequent statistical analysis is drawn from this 'temporary' local table. After the process is complete, the local table is truncated.
-- Edited 08/13/2012 # 1217 hours --
Ran the shown query on the SQL Server Management Console, took 1 minute 38 seconds to complete according to the query timer provided by the console.
-- Edit 08/15/2012 # 1531 hours --
Tried to run query as VBA DoCmd.RunSQL statement to populate a temporary table using the following code:
INSERT INTO tblTempRecorderDataStatsByArea ( strAreaAssigned, datFirstRecord,
datLastRecord, intAveTempC, intAveRH, intRecordCount )
SELECT dbo_tblRecorderLogs.strAreaAssigned, Min(dbo_tblRecorderLogs.datDateRecorded)
AS MinOfdatDateRecorded, Max(dbo_tblRecorderLogs.datDateRecorded) AS MaxOfdatDateRecorded,
Round(Avg(dbo_tblRecorderLogs.intTempCelsius),2) AS AveTempC,
Round(Avg(dbo_tblRecorderLogs.intRHRecorded),2) AS AveRHRecorded,
Count(dbo_tblRecorderLogs.strAreaAssigned) AS CountOfstrAreaAssigned FROM
dbo_tblRecorderLogs GROUP BY dbo_tblRecorderLogs.strAreaAssigned ORDER BY
dbo_tblRecorderLogs.strAreaAssigned
The problem arises when the code is executed, the query takes so long - it encounters Timeout before it finishes. Still hoping for a 'magic bullet' to fix this...
-- Edited 08/20/2012 # 1241 hours --
The only 'quasi' solution I've found is running the failed query repeatedly (sort of priming the pump, as it were) so that when the query is called again by my program - it has a relative chance of actually completing before the ODBC SQL Server driver times out. Basically, a filthy filthy hack - but I don't have a better one to combat this issue.
I've tried creating a view, which works on the server side - but doesn't speed things up.
The proper fields being aggregated are indexed properly, so I can't make any changes there.
I am only pulling information from the database that is immediately useful to user - no 'SELECT * madness' going on here.
I think I am, officially, out of things to try - aside from throwing raw computing horsepower at the problem, which isn't a solution right now as the item isn't live, and I have no budget to procure better hardware. I will post this as an 'answer' and leave it up until Sept 3rd - where if I do not have better answers, I will accept my own answer and accept defeat.
When I've had to run min/max functions on several fields from the same table I've often found it quicker to do each column separately as a subquery in the from line of the main/outer query.
So your query would be like this:
SELECT rLogs1.strAreaAssigned, rLogs1.FirstRecorderDate, rLogs2.LastRecorderDate, rLog3.AverageTempC, rLogs4.AverageRH, rLogs5.Records
FROM (((
(SELECT strAreaAssigned, min(datDateRecorded) as FirstRecorderDate FROM dbo.tblRecorderLogs GROUP BY strAreaAssigned) rLogs1
inner join
(SELECT strAreaAssigned, Max(datDateRecorded) as LastRecordedDate, FROM dbo.tblRecorderLogs GROUP BY strAreaAssigned) rLogs2
on rLogs1.strAreaAssigned = rLogs2.strAreaAssigned)
inner join
(SELECT strAreaAssigned, Round(Avg(intTempCelsius),2) AS AverageTempC, FROM dbo.tblRecorderLogs GROUP BY strAreaAssigned) rLogs3
on rLogs1.strAreaAssigned = rLogs3.strAreaAssigned)
inner join
(SELECT strAreaAssigned, Round(Avg(intRHRecorded),2) AS AverageRH, FROM dbo.tblRecorderLogs GROUP BY strAreaAssigned) rLogs4
on rLogs1.strAreaAssigned = rLogs4.strAreaAssigned)
inner join
(SELECT strAreaAssigned, Count(strAreaAssigned) AS Records, FROM dbo.tblRecorderLogs GROUP BY strAreaAssigned) rLogs5
on rLogs1.strAreaAssigned = rLogs5.strAreaAssigned
ORDER BY rLogs1.strAreaAssigned;
If you take your query and the one above, copy them into the same query window in SQL Server and run the estimated execution plan you should be able to compare them and see which one works better.

PostGIS geometry database query

I have several tables that contain multipolygons. I need to find points within these polygons that I can use in my java test class. What I have been doing is sending a query to return all the multi polygons, choose a vertex to use as a point, and most times it works.
However these tables represent risk data, 1 in 100, 1 in 200 etc, and so some of the points are shared between tables (the higher risk multi polygons are encapsulated by the lower risk). what query can I use to return a point that will be within 1 multipolygon in 1 table, but not in any others that I specify?
the tables are river_100_1k, river_200_1k, and river_1000_1k
Well you could do a multiple left join:
SELECT a.gid, a.the_geom FROM pointsTable a
LEFT JOIN river_100_1k b
ON ST_Intersects(a.the_geom, b.the_geom)
LEFT JOIN
river_200_1k c
ON NOT ST_Intersects(a.the_geom, c.the_geom) -- Not Intersects
LEFT JOIN
river_1000_1k d
ON NOT ST_Intersects(a.the_geom, d.the_geom) -- Not Intersects
WHERE
AND c.gid IS NULL AND d.gid IS NULL AND b.gid=2 AND c.gid=2 AND d.gid=2 ;
I'm not sure if I understand correctly but this is the path you should take.
Use ST_PointOnSurface(polygon) to get a point within a polygon.

How do I search a "Property Bag" table in SQL?

I have a basic "property bag" table that stores attributes about my primary table "Card." So when I want to start doing some advanced searching for cards, I can do something like this:
SELECT dbo.Card.Id, dbo.Card.Name
FROM dbo.Card
INNER JOIN dbo.CardProperty ON dbo.CardProperty.IdCrd = dbo.Card.Id
WHERE dbo.CardProperty.IdPrp = 3 AND dbo.CardProperty.Value = 'Fiend'
INTERSECT
SELECT dbo.Card.Id, dbo.Card.Name
FROM dbo.Card
INNER JOIN dbo.CardProperty ON dbo.CardProperty.IdCrd = dbo.Card.Id
WHERE (dbo.CardProperty.IdPrp = 10 AND (dbo.CardProperty.Value = 'Wind' OR dbo.CardProperty.Value = 'Fire'))
What I need to do is to extract this idea into some kind of stored procedure, so that ideally I can pass in a list of property/value combinations and get the results of the search.
Initially this is going to be a "strict" search meaning that the results must match all elements in the query, but I'd also like to have a "loose" query so that it would match any of the results in the query.
I can't quite seem to wrap my head around this one. My previous version of this was to do generate some massive SQL query to execute with a lot of AND/OR clauses in it, but I'm hoping to do something a little more elegant this time. How do I go about doing this?
it seems to me that you have an EAV model here.
if you're using sql server 2005 and up i'd suggest you use XML datatype for this:
http://weblogs.sqlteam.com/mladenp/archive/2006/10/14/14032.aspx
makes searching and stuff much easier with built in xml querying capabilities.
if you can't change your model then look at this:
http://weblogs.sqlteam.com/davidm/articles/12117.aspx

Resources