Postgresql query won't work - postgresql

query
any help appreciated,a week now and I am stuck -
many thanks if you can.
I added an image of the problem but it's disappeared
WITH SITESmin as (
SELECT public.acc.Location_Easting_OSGR, public.acc.Location_Northing_OSGR
FROM acc Sites ,
ORDER BY ( acc.Location_Easting_OSGR - Sites.SITE_ETG ) * ( acc.Location_Easting_OSGR - Sites.SITE_ETG ) + (acc.Location_Northing_OSGR - "public"."Sites"."SITE_ETG" ) * ( acc.Location_Northing_OSGR - "public"."Sites"."SITE_NTG" )
LIMIT 1
)
UPDATE ACC
SET acc.Location_Easting_OSGR = SITESmin.acc.Location_Easting_OSGR,
acc.Location_Northing_OSGR = SITESmin.acc.Location_Northing_OSGR
FROM SITESmin;
Here's the error:
Error : ERROR: syntax error at or near "ORDER"
LINE 4: ORDER BY ( acc.Location_Easting_OSGR - Sites.SITE_ETG )...
The ^ carat appears just after the Line 4: colon

on second look i noticed that this query has several problems.If you are using alias then stick to that alias, you have lots of fields defined wrongly or your query you posted has some missing parts and are not present in your example. and update part looks like is missing where condition ....
for example
SELECT public.acc.Location_Easting_OSGR, public.acc.Location_Northing_OSGR
yet you defined alias "Sites", which by the way is missing "as" syntax, it shouldve been
FROM acc as Sites
WITH SITESmin as (
SELECT Sites.Location_Easting_OSGR, Sites.Location_Northing_OSGR
FROM acc as Sites --, <--- this coma was is causing that error, it does not belong there or some code is missing
ORDER BY (Sites.Location_Easting_OSGR - Sites.SITE_ETG ) * ( Sites.Location_Easting_OSGR - Sites.SITE_ETG ) + (Sites.Location_Northing_OSGR - Sites.SITE_ETG ) * ( Sites.Location_Northing_OSGR - Sites.SITE_NTG )
LIMIT 1
)
UPDATE ACC
SET acc.Location_Easting_OSGR = SITESmin.Location_Easting_OSGR,
acc.Location_Northing_OSGR = SITESmin.Location_Northing_OSGR
FROM SITESmin
--- missing where condition?
;

Related

Get Substrings From DB2 Column

I Have: AAAA/DATA1/Data2;xyx;pqr
this data
I want only:DATA1 And Data2
If this is for a specific row, maybe use SUBSTR? Something like
SELECT
SUBSTR(column, 6, 5) AS col1
, SUBSTR(column, 13, 5) AS col2
FROM table
Here is something else you can do.. Although it gets pretty complicated, and this isn't the exact answer you are looking for but it will get you started. Hope this helps:
WITH test AS (
SELECT characters
FROM ( VALUES
( 'AAAA/DATA1/Data2;xyx;pqr'
) )
AS testing(characters)
)
SELECT
SUBSTR(characters, 1, LOCATE('/', characters) - 1) AS FIRST_PART
, SUBSTR(characters, LOCATE('/', characters) + 1) AS SECOND_PART
, SUBSTR(characters, LOCATE('/', characters, LOCATE('/', characters) + 1) + 1)
AS THIRD_PART
FROM test
;
DB2 does not have a single function for this, unfortunately. Check out this answer here: How to split a string value based on a delimiter in DB2

Multiple AND statements in a FileMaker calculation

I want to calculate if a value falls outside of 10% of the last two values added to a database. This calculation is not giving me correct feedback when I have 'Weight" values close to 10, or from 100-110. Otherwise it works fine.
Case (
Get(RecordNumber) ≤ 2 ; "Continue Collecting Data" ;
(((GetNthRecord ( Weight ; Get(RecordNumber)-2))*.9) ≤ Weight) and
(((GetNthRecord ( Weight ; Get(RecordNumber)-2))*1.1) ≥ Weight) and
(((GetNthRecord ( Weight ; Get(RecordNumber)-1))*.9) ≤ Weight) and
(((GetNthRecord ( Weight ; Get(RecordNumber)-1))*1.1) ≥ Weight);
"Stable";
"Unstable")
I’m going to start with the assumption that your table includes fields for both the primary key and the creation timestamp. If not, I would highly recommend adding both to this table and every other table you create.
Assuming these fields are in place, you need to create another occurrence of the table on which this layout is based, then relate the primary key to itself via a Cartesian (×) join. Sort the relationship by creation timestamp descending. Your calculation is then:
Case (
(((GetNthRecord ( Weight ; 1 ) *.9 ) ≤ Weight) and
(((GetNthRecord ( Weight ; 1 ) *1.1 ) ≥ Weight) and
(((GetNthRecord ( Weight ; 2 ) *.9 ) ≤ Weight) and
(((GetNthRecord ( Weight ; 2 ) *1.1 ) ≥ Weight);
"Stable";
"Unstable")
Another thing I noticed is that your code is kind of complex. The Let function can make things easier to read, and your four criteria can be cut down to whether either difference is out of range. So, a simpler version becomes:
Let ( [
#weight1 = GetNthRecord ( all::weight ; 1 ) ;
#weight2 = GetNthRecord ( all::weight ; 2 )
] ; //end define Let
Case (
Abs ( #weight1 - weight ) > .1 ; "Unstable" ;
Abs ( #weight2 - weight ) > .1 ; "Unstable" ;
"Stable"
) //end Case
) //end Let
Does that help?
Assuming you are using FileMaker v12 or later, this looks like a good place to use the ExecuteSQL function (not the script step) to retrieve the last two values. You could do something like this:
Let (
sqlQuery = "
SELECT t.weight
FROM MyTable t
WHERE t.id <> ?
ORDER BY t.id DESC
FETCH FIRST 2 ROWS ONLY
" ;
ExecuteSQL ( sqlQuery ; "" ; "" ; MyTable::id )
)
This query assumes you have a unique 'id' field (i.e. a primary key) that's defined as an 'auto-enter serial' value. The WHERE clause makes sure that the current record (presumably the one the user is entering) is not included in the query. The ORDER BY DESC clause forces the last two records to the top where we can fetch the 'weight' values easily into a value list.
Assuming you use a 'Set Variable' script step to put the query results into $lastValues, you can then test for whether they are in range like so:
Let ( [
lastValue1 = GetValue ( $lastValues ; 1 ) ;
lastValue2 = GetValue ( $lastValues ; 2 ) ;
Value1_InRange = lastValue1 - Abs ( lastValue1 - weight ) >= ( 0.9 * lastValue1 ) ;
Value2_InRange = lastValue2 - Abs ( lastValue2 - weight ) >= ( 0.9 * lastValue2 )
] ;
Value1_InRange and Value2_InRange // returns 1 if both values within range, 0 if not
)
If I were doing this, I would put the above range-checking code into a custom function so it's generic and can be easily reused:
IsWithinRange ( valueToTest ; lastValue ; range ) =
lastValue - Abs ( lastValue - valueToTest ) >= ( ( 1 - range ) * lastValue )
Then the above range-checking code can be reduced to:
IsWithinRange ( MyTable::weight ; GetValue ( $lastValues ; 1 ) ; 0.1 ) &
IsWithinRange ( MyTable::weight ; GetValue ( $lastValues ; 2 ) ; 0.1 )
And one last note.. if you use the ExecuteSQL function in a calculated field, be sure to make it 'unstored' so that it only executes when needed. However, I would recommend you avoid that altogether and simply call it from a script step like 'Set Variable'. That way you can control exactly when it executes.
Hope that helps!

FMP 14 - Auto Populate a Field based on a calculation

I am using FMP 14 and would like to auto-populate field A based on the following calulation:
If ( Get ( ActiveLayoutObjectName ) = "tab_Visits_v1" ; "1st" ) or
If ( Get ( ActiveLayoutObjectName ) = "tab_Visits_v2" ; "2nd" ) or
If ( Get ( ActiveLayoutObjectName ) = "tab_Visits_v3" ; "3rd" ) or
If ( Get ( ActiveLayoutObjectName ) = "tab_Visits_v4" ; "4th" ) or
If ( Get ( ActiveLayoutObjectName ) = "tab_Visits_v5" ; "5th" ) or
If ( Get ( ActiveLayoutObjectName ) = "tab_Visits_v6" ; "6th" )
The above code is supposed to auto-populate the value 1st, 2nd, 3rd ... in field A depending on the name of the object the Get (ActiveLayoutObjectName) function returns. I have named each of my tabs, but the calculation is only returning 0.
Any help would be appreciated.
thanks.
The way your calculation is written makes very little sense. Each one of the If() statements returns a result of either "1st", "2nd", etc. or nothing (an empty string). You are then applying or to all these results. Since only of them can be true, your calculation is essentially doing something like:
"" or "2nd" or "" or "" or "" or ""
which happens to return 1 (true), but has no useful meaning.
You should be using the Case() function here:
Case (
Get ( ActiveLayoutObjectName ) = "tab_Visits_v1" ; "1st" ;
Get ( ActiveLayoutObjectName ) = "tab_Visits_v2" ; "2nd" ;
Get ( ActiveLayoutObjectName ) = "tab_Visits_v3" ; "3rd" ;
Get ( ActiveLayoutObjectName ) = "tab_Visits_v4" ; "4th" ;
Get ( ActiveLayoutObjectName ) = "tab_Visits_v5" ; "5th" ;
Get ( ActiveLayoutObjectName ) = "tab_Visits_v6" ; "6th"
)
Note also that a calculation field may not always refresh itself as a result of user switching a tab. This refers to an unstored calculation field; if you are trying to use this as the formula to be auto-entered into a "regular' (e.g. Text) field, it will never update.
Added:
Here is our situation. We see a patient a maximum of 6 times. We have
a tab for each one of those 6 visits.
I would suggest you use a portal to a related table of Visits instead of a tab control. A tab control is designed to display fixed components of user interface - not dynamic data. And certainly not data split into separate records. You should have only one unique record for each patient - and as many records for each patient's visits as may be necessary (potentially unlimited).
If you like, you can use the portal rows as buttons to select a specific visit to view in more detail (similar to a tab control, except that the portal shows the "tabs" as vertical rows). A one-row portal to the same Visits table, filtered by the user selection, would work very well for this purpose, I believe.
With 1. .... it would be easy:
Right (Get ( ActiveLayoutObjectName ) ; 1) & "."
Thanks for pointing out, that my first version does not work.

OrientDB Removing one result set from another using the difference() function

We are using version v.1.7-rc2 of OrientDB, embedded in our application, and I'm struggling to figure out a query for removing one set of results from another set of results.
For a simplified example, we have a class of type "A" which is organized in a directional hierarchy. The class has a "name" attribute defined as a string (referring to areas, regions, counties, cities, etc), and a "parent" edge defining a relationship from the child instances to the parent instances.
I was able to find the intersection of the result sets from the two sub-queries of my hierarchy using the instance() function:
select expand( $1 ) LET $2 = ( select from (traverse in('parent') from (select from A where name = 'Eastern')) where $depth > 0 and name like '%a%' ), $3 = ( select from (traverse in('parent') from (select from A where name = 'Eastern')) where $depth > 0 and name like '%o%' ), $1 = intersect( $2, $3 )
I thought I could accomplish the opposite effect if I used the difference() function:
select expand( $1 ) LET $2 = ( select from (traverse in('parent') from (select from A where name = 'Eastern')) where $depth > 0 and name like '%a%' ), $3 = ( select from (traverse in('parent') from (select from A where name = 'Eastern')) where $depth > 0 and name like '%o%' ), $1 = difference( $2, $3 )
but it returns zero records, when the sub queries for $2 and $3 run separately return record sets that overlap. What am I failing to understand? I've searched the forums and documentation, but haven't figured it out.
In the end, I want to take vertices found in one result set, and remove from it any vertices found in a second result set. I essentially want the analogous behavior of the SQL EXCEPT operator (https://en.wikipedia.org/wiki/Set_operations_%28SQL%29#EXCEPT_operator).
Any ideas or directions would be extremely helpful!
Regards,
Andrew

Is it possible to refactor this statement to remove the subquery?

I'm trying to take data from one column, MyTable.SSN, and copy it to another in the same table, MyTable.SSNWithDashes, just formatted differently. If MyTable.SSN doesn't have exactly 9 digits, I don't care to process it at all.
I've tried this:
IF( SELECT LEN( [SSN] ) FROM [MyTable] ) = 9
UPDATE [MyTable] SET [SSNWithDashes] = LEFT( [SSN], 3 ) + '-' + SUBSTRING( [SSN], 4, 2 ) + '-' + RIGHT( [SSN], 4 )
ELSE
UPDATE [MyTable] SET [SSNWithDashes] = NULL
While this works, it throws an error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
While I do understand what the warning is saying, I'm not really sure how to go about this differently.
How can I refactor this to remove that warning (and perhaps read a little cleaner)?
UPDATE dbo.[MyTable]
SET [SSNWithDashes] = CASE
WHEN LEN(SSN) = 9 THEN
LEFT([SSN],3) + '-' + SUBSTRING([SSN],4,2) + '-' + RIGHT([SSN],4)
ELSE NULL
END;
Assuming your SSNWithDashes is already NULL then
UPDATE dbo.[MyTable]
SET [SSNWithDashes] = LEFT([SSN],3) + '-' + SUBSTRING([SSN],4,2) + '-' + RIGHT([SSN],4)
WHERE LEN(SSN) = 9
Every other rows remain NULL