OrientDB - Update with SUBSELECT - orientdb

I want to update some rows of my table basing on other rows of the same table:
I try this:
UPDATE MyTable set myField =
(SELECT T1.myField
FROM MyTable T1
WHERE T1.id.substring(start,stop) = MyTable.id.substring(start,stop))
But OrientDB throws an error like this:
com.orientechnologies.orient.core.sql.OCommandSQLParsingException: Error on parsing command at position #XXX: Invalid keyword 'T1' Command:

first of all you in OrientDB you can't use Alias on Classes.
In this case you could use $parent.$current in a subquery, something like:
> update MyTable set myField = (
> select myField
> from MyTable
> where myField is null
> and id.substring(8,13) = $parent.$current.id.substring(8,13) and something else...
> ) where myField is null and something else...
Be careful to the length of the id...
Best Regards
M.

This is not a string update, but an integer update in place. Using the provided GratefulDeadDatabase, you can do:
CONNECT remote:localhost/GratefulDeadConcerts;
SELECT performances FROM v;
----+------+------------
# |#CLASS|performances
----+------+------------
0 |null |null
1 |null |5
2 |null |1
3 |null |531
4 |null |394
----+------+------------
UPDATE v SET performances = eval('performances + 2') WHERE performances IS NOT NULL;
SELECT performances FROM v;
----+------+------------
# |#CLASS|performances
----+------+------------
0 |null |null
1 |null |7
2 |null |3
3 |null |533
4 |null |396
----+------+------------
So the update works on the data in place. I'm fairly new to OrientDB so maybe an expert can tell me if I just did something horribly horribly wrong.
UPDATE
Notice that in your example you are updating the table with values from the same table. That is, from MyTable into MyTable (unless I misunderstood your query) and even within the same row. You can use criteria on the WHERE clause to only update rows of interest. In my example, that was
WHERE performances IS NOT NULL

Related

PySpark sql CASE fails

i've encoutered strange behaviour when working with PySpark sqlContext. The problem is best ilustrated in the code below.
I am checking the value of COLUMN in simple case statement. However WHEN is not triggered even though the condition checks TRUE and always jumps to ELSE. Am I doing something wrong with the syntax here?
dataTest = spark.sql("""SELECT
COLUMN > 1,
CASE COLUMN
WHEN COLUMN > 1 THEN 1
ELSE COLUMN
END AS COLUMN_2,
COLUMN
FROM TABLE
""")
dataTest.sort(col("COLUMN").desc()).show(5, False)
+---------------+-------------+---------+
|COLUMN >1 |COLUMN_2 |COLUMN |
+---------------+-------------+---------+
|true |14 |14 |
|true |5 |5 |
|true |4 |4 |
|true |3 |3 |
|true |2 |2 |
+---------------+-------------+---------+
You are missing the syntax, try:
SELECT
COLUMN > 1,
CASE WHEN COLUMN > 1 THEN 1
ELSE COLUMN
END AS COLUMN_2,
COLUMN
FROM TABLE
Notice there's no COLUMN between CASE and WHEN keywords.

Display %ROWCOUNT value in a select statement

How is the result of %ROWCOUNT displayed in the SQL statement.
Example
Select top 10 * from myTable.
I would like the results to have a rowCount for each row returned in the result set
Ex
+----------+--------+---------+
|rowNumber |Column1 |Column2 |
+----------+--------+---------+
|1 |A |B |
|2 |C |D |
+----------+--------+---------+
There are no any simple way to do it. You can add Sql Procedure with this functionality and use it in your SQL statements.
For example, class:
Class Sample.Utils Extends %RegisteredObject
{
ClassMethod RowNumber(Args...) As %Integer [ SqlProc, SqlName = "ROW_NUMBER" ]
{
quit $increment(%rownumber)
}
}
and then, you can use it in this way:
SELECT TOP 10 Sample.ROW_NUMBER(id) rowNumber, id,name,dob
FROM sample.person
ORDER BY ID desc
You will get something like below
+-----------+-------+-------------------+-----------+
|rowNumber |ID |Name |DOB |
+-----------+-------+-------------------+-----------+
|1 |200 |Quigley,Neil I. |12/25/1999 |
|2 |199 |Zevon,Imelda U. |04/22/1955 |
|3 |198 |O'Brien,Frances I. |12/03/1944 |
|4 |197 |Avery,Bart K. |08/20/1933 |
|5 |196 |Ingleman,Angelo F. |04/14/1958 |
|6 |195 |Quilty,Frances O. |09/12/2012 |
|7 |194 |Avery,Susan N. |05/09/1935 |
|8 |193 |Hanson,Violet L. |05/01/1973 |
|9 |192 |Zemaitis,Andrew H. |03/07/1924 |
|10 |191 |Presley,Liza N. |12/27/1978 |
+-----------+-------+-------------------+-----------+
If you are willing to rewrite your query then you can use a view counter to do what you are looking for. Here is a link to the docs.
The short version is you move your query into a FROM clause sub query and use the special field %vid.
SELECT v.%vid AS Row_Counter, Name
FROM (SELECT TOP 10 Name FROM Sample.Person ORDER BY Name) v
Row_Counter Name
1 Adam,Thelma P.
2 Adam,Usha J.
3 Adams,Milhouse A.
4 Allen,Xavier O.
5 Avery,James R.
6 Avery,Kyra G.
7 Bach,Ted J.
8 Bachman,Brian R.
9 Basile,Angelo T.
10 Basile,Chad L.

Using Traverse from to project the records in OrientDB

I'm using the Vehicle History database with OrientDb Studio 2.2.8, and I want to project all of the records of the automobile class that are made by Kia.
The schema for the database looks like this:
(Automobile) --isModel--> (Model) --isMake--> (Make)
where Automobile, Model, and Make are vertices and isModel, and isMake are edge types.
I want to use a traverse statement to return an equivalent result set as I get from this command:
Select expand(in('isMake').in('isModel')) from Make where name = "Kia"
whose result is...
+----+--------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|# |#RID |#CLASS |color |convertib|out_isMod|trailerHi|emissions|safety |out_Purch|VIN |
+----+--------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|0 |#17:1441|Automo...|White |true |[#24:1...|false |2016-0...|2014-0...|[#23:5...|840CDC...|
|1 |#17:1576|Automo...|Maroon |true |[#24:1...|false |2010-0...|2004-0...|[#23:5...|E71761...|
|2 |#17:1503|Automo...|Dark Gray|true |[#24:1...|false |2009-0...|2016-1...|[#23:5...|FAEB6F...|
+----+--------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
I tried running this:
Select
from (traverse in from Make while $depth <= 2)
where name = "Kia"
I just get one record returned, and it's not of the Automobile class like I expected it to be. It is from Make.
+----+-------+------+----+-------------------------------------+----------------------------+
|# |#RID |#CLASS|name|in_isMake |out_Sold |
+----+-------+------+----+-------------------------------------+----------------------------+
|0 |#15:612|Make |Kia |[#25:1767,#25:2036,#25:2067,#25:2131]|[#22:5153,#22:5383,#22:5655]|
+----+-------+------+----+-------------------------------------+----------------------------+
Basically, I want to use a Traverse starting from Make to project the three Kia automobiles in the database.
Can you try this?
SELECT FROM (TRAVERSE in()
FROM (SELECT FROM Make where name='Kia'))
WHERE #class='Automobile'

Postgresql select, show fixed count rows

Simple question. I have a table "tablename" with 3 rows. I need show 5 rows in my select when count rows < 5.
select * from tablename
+------------------+
|colname1 |colname2|
+---------+--------+
|1 |AAA |
|2 |BBB |
|3 |CCC |
+---------+--------+
In this query I show all rows in the table.
But I need show 5 rows. 2 rows is empty.
For example (I need):
+------------------+
|colname1 |colname2|
+---------+--------+
|1 |AAA |
|2 |BBB |
|3 |CCC |
| | |
| | |
+---------+--------+
Last 2 rows is empty.
It is possible?
Something like this:
with num_rows (rn) as (
select i
from generate_series(1,5) i -- adjust here the desired number of rows
), numbered_table as (
select colname1,
colname2,
row_number() over (order by colname1) as rn
from tablename
)
select t.colname1, t.colname2
from num_rows r
left outer join numbered_table t on r.rn = t.rn;
This assigns a number for each row in tablename and joins that to a fixed number of rows. If you know that your values in colname1 are always sequential and without gaps (which is highly unlikely) then you can remove the generation of row numbers in the second CTE using row_number().
If you don't care which rows are returned, you can leave out the order by part - but then the rows that are matched will be random. Leaving out the order by will be a bit more efficient.
The above will always return exactly 5 rows, regardless of how many rows tablename contains. If you want at least 5 rows, then you need to flip the outer join:
....
select t.colname1, t.colname2
from numbered_table t
left outer join num_rows r on r.rn = t.rn;
SQLFiddle example: http://sqlfiddle.com/#!15/e5770/3

SQL Joining two table

I am struggling, maybe the simplest problem ever. My SQL knowledge pretty much limits me from achieving this. I am trying to build an sql query that should show JobTitle, Note and NoteType. Here is the thing, First job doesn't have any note but we should see it in the results. System notes never and ever should be displayed. An expected result should look like this
Result:
--------------------------------------------
|ID |Title |Note |NoteType |
--------------------------------------------
|1 |FirstJob |NULL |NULL |
|2 |SecondJob |CustomNot1|1 |
|2 |SecondJob |CustomNot2|1 |
|3 |ThirdJob |NULL |NULL |
--------------------------------------------
.
My query (doesn't work, doesn't display third job)
SELECT J.ID, J.Title, N.Note, N.NoteType
FROM JOB J
LEFT OUTER JOIN NOTE N ON N.JobId = J.ID
WHERE N.NoteType IS NULL OR N.NoteType = 1
My Tables:
My JOB Table
----------------------
|ID |Title |
----------------------
|1 |FirstJob |
|2 |SecondJob |
|3 |ThirdJob |
----------------------
My NOTE Table
--------------------------------------------
|ID |JobId |Note |NoteType |
--------------------------------------------
|1 |2 |CustomNot1|1 |
|2 |2 |CustomNot2|1 |
|3 |2 |SystemNot1|2 |
|4 |2 |SystemNot3|2 |
|5 |3 |SystemNot1|2 |
--------------------------------------------
This can't be true together (NoteType can't be NULL as well as 1 at the same time):
WHERE N.NoteType IS NULL AND N.NoteType = 1
You may want to use OR instead to check if NoteType is either NULL or 1.
WHERE N.NoteType IS NULL OR N.NoteType = 1
EDIT: With corrected query, your third job will not be retrieved as JOB_ID is matching but its the row getting filtered out because of the where condition.
Try below as work around to get the third job with null values.
SELECT J.ID, J.Title, N.Note, N.NoteType
FROM JOB J
LEFT OUTER JOIN
( SELECT JOBID NOTE, NOTETYPE FROM NOTE
WHERE N.NoteType IS NULL OR N.NoteType = 1) N
ON N.JobId = J.ID
just exclude the systemNotes and use a sub-select:
select * from job j
left outer join (
select * from note where notetype!=2
) n
on j.id=n.jobid;
if you include the joined table into where then left outer join might work as an inner join.