select only vertex from TRAVERSE outE(), inV() FROM ... command - orientdb

I have a SQL Command that currently works just fine as below
select from (traverse outE(), inV() from (select from Foo where name='root') while active=true) where #class='Foo'
However I think it will not work for the case I have many different types of vertex connected together. Therefore I need to replace the where condition with something like
select from (traverse outE(), inV() from (select from Foo where name='root') while active=true) where #elementType='Vertex'
Is there special function to determine element type which is available in Java API (OrientElement.getElementType())?

use this as where condition:
where #this instanceof 'V'

Related

Qlik Sense Syntax in Data Loader Script

How it would be this query in Qlik Sense syntax in data loader script?
TABLA_UTIL:
SQL
SELECT "PERIODO", SUM(DEUDAFINAL) as "DEUDAFINAL"
FROM "DL_RG_ANALYTICS"."SH_PROVISION" PRO WHERE ORG='628'
GROUP BY PERIODO
concatenate
SQL
SELECT OL.PERIODO, SUM(ABIERTA/1000000)+ DEUDA/1000000
FROM "DL_RG_ANALYTICS"."SH_OTRAS_LINEAS" OL LEFT JOIN SH_SALDO_NO_IDEN_RUT PRO ON(OL.PERIODO=PRO.PERIODO)
WHERE ((ol.TIPO_DEUDA='TRASPASO' AND ol.DEFINICION='SALDO' )
OR (ol.TIPO_DEUDA='SAE' AND ol.DEFINICION='SALDO' )
OR (ol.TIPO_DEUDA='REPACTACIONES' AND ol.DEFINICION='SALDO')
OR (ol.TIPO_DEUDA='RENEGOCIADO' AND ol.DEFINICION='SALDO' )
OR (ol.TIPO_DEUDA='AVANCE_EFECTIVO' AND ol.DEFINICION='SALDO' ))
AND PRO.TipoTarjeta='ABIERTA'
GROUP BY OL.PERIODO, PRO.DEUDA
Any help is welcome, thanks.
Hy,
that's easy, so cheer up.
If all field names in each table are identical, Qlik Sense will set this to one immediately after the other. To make it unambiguous:
concatenate(table_name)
is a good idea.
Look at this:
qlik script guide concatenate
Here's your example:
LIB CONNECT TO 'your_database';
TABLA_UTIL:
Load *;
SQL
SELECT
"PERIODO",
SUM(DEUDAFINAL) as "DEUDAFINAL"
FROM
"DL_RG_ANALYTICS"."SH_PROVISION" PRO WHERE ORG='628'
GROUP BY PERIODO;
LIB CONNECT TO 'your_second_database'; // where necessary
concatenate(TABLA_UTIL) //all field names must be the same
Load *;
SQL
SELECT
OL.PERIODO as "PERIODO",
SUM(ABIERTA/1000000)+ DEUDA/1000000 as "DEUDAFINAL"
FROM
"DL_RG_ANALYTICS"."SH_OTRAS_LINEAS" OL LEFT JOIN SH_SALDO_NO_IDEN_RUT PRO ON(OL.PERIODO=PRO.PERIODO)
WHERE ((ol.TIPO_DEUDA='TRASPASO' AND ol.DEFINICION='SALDO' )
OR (ol.TIPO_DEUDA='SAE' AND ol.DEFINICION='SALDO' )
OR (ol.TIPO_DEUDA='REPACTACIONES' AND ol.DEFINICION='SALDO')
OR (ol.TIPO_DEUDA='RENEGOCIADO' AND ol.DEFINICION='SALDO' )
OR (ol.TIPO_DEUDA='AVANCE_EFECTIVO' AND ol.DEFINICION='SALDO' ))
AND PRO.TipoTarjeta='ABIERTA'
GROUP BY OL.PERIODO, PRO.DEUDA;
//done
Disagree with previous answer ,
Concatenate is used to concatenate tables with different fields names.
Concatenation of tables with identical set of fields is automatic and can be avoided with NOCONCATENATE keyword (before LOAD)

Passing a column name as an argument for KDB select query?

I would like to pass a column name into a Q function to query a loaded table.
Example:
getDistinct:{[x] select count x from raw}
getDistinct "HEADER"
This doesn't work as the Q documentation says I cannot pass column as arguments. Is there a way to bypass this?
When q interprets x it will treat it as a string, it has no reference to the column, so your output would just be count "HEADER".
If you want to pass in the column as a string you need to build the whole select statement then use value
{value "select count ",x," from tab"} "HEADER"
However, the recommended method would be to use a functional select. Below I use parse to build the functional select equivalent using the parse tree.
/Create sample table
tab:([]inst:10?`MSFT`GOOG`AAPL;time:10?.z.p;price:10?10f)
/Generate my parse tree to get my functional form
.Q.s parse "select count i by inst from tab"
/Build this into my function
{?[`tab;();(enlist x)!enlist x;(enlist `countDistinct)!enlist (#:;`i)]} `inst
Note that you have to pass the column in as a symbol. Additionally the #:i is just the k equivalent to count i.
Update for multiple columns
tab:([]inst:10?`MSFT`GOOG`AAPL;time:10?.z.p;price:10?10f;cntr:10`HK`SG`UK`US)
{?[`tab;();(x)!x;(enlist `countDistinct)!enlist (#:;`i)]} `inst`cntr
To get the functional form of a select statement, I recommend using buildSelect. Also, reduce the scope of parenthesis, i.e. use enlist[`countDistinct] instead of (enlist `countDistinct).

How to get specific user all versions of an object through dql?

I want to get all versions of documents from dm_document
code I have written is
SELECT object_name, r_version_label FROM dm_sysobject where ( r_modifier='kishoren') and (r_object_id in (select r_object_id from dm_sysobject where any r_version_label>='1.0'))
it is giving only current version labels
but I want out put like
select r_object_id,i_chronicle_id,r_version_label from dm_sysobject(all) where i_chronicle_id='090008868006d5be' and owner_name='swathi'
This will give required output as above

find path between vertices using edge properties in OrientDB

Is there a way to find a path between 2 vertices only including edges having a property with specific value in orient DB ?
I am able to find the path between 2 vertices but not able to filter out based on edge properties.
If you want the paths between 2 vertices, then you can do:
SELECT $path as path
FROM (
TRAVERSE outE(), inV() FROM #13:1
)
WHERE #rid == '14:2'
This basically goes through the out edges from #13:1, building the path. It will keep only those that end with the rid #14:2. One thing to note is that, it will return several paths, but if 2 two paths share a common track then only one of those will be retrieved (thats a thing with traverse command that for preventing loops and efficiency does that)
If you have further conditions you want to apply to the traversal, you can put them in the WHILE. Say you want to also take into consideration the value of test attribute from the edges:
SELECT $path as path
FROM (
TRAVERSE outE(), inV() FROM #13:1
WHILE (#class == 'V') OR (#class == 'E' AND test == 3)
)
WHERE #rid == '14:2'
Here you need this 2 conditions because you are traversing both vertices and edges, so if its an edge you want to check on test attribute, if its a vertex, no condition, keep traversing.
NOTE:
There's a caveat from Traverse command where you cannot get all the possible paths between 2 vertices (excluding the paths with cicles), because traverse avoids traversing a node more than once, so the $path will only have one path containing the target vertex. Since we were filtering paths checking for the id of the traversed node, we only get one path be cause it doesnt traverse a node more than once. We need a way to find the paths without relying on traversed nodes....
we've got edges! Here is the workaround:
BEGIN;
LET target = SELECT #rid as rid, inE() as ins FROM <target_id>
LET paths = SELECT $path as path
FROM (TRAVERSE outE(), inV() FROM <source_id>)
WHERE #rid in $target['ins'];
if ($paths.size() > 0) {
LET result = SELECT path.append(".inV(").append($target['rid'][0]).append(")") from $paths;
}
if ($paths.size() == 0) {
LET result = SELECT FROM $paths;
}
COMMIT;
RETURN $result;
So we traverse from the source every path, but we filter those that includes the incomming edges from our target. If a path starting from the source includes an incomming edge from the target, its definitely a valid path between both.
Then we do a little trick to include the target vertex in the path so we can return a nice and complete path string.
This will return all paths between the 2 vertices, including the rels. It may be pretty greedy but is the only way i found to get all possible paths.
Don't know, if you're still looking for an answer, but you could try smth like this:
select from (traverse * from #13:1 while #rid <> #14:2) where test = 3
where #13:1 is an id for A, #14:2 - for E.

Reusing ?'s on a DBI prepare

Is there a way to reuse the ?'s used on a DBI prepare statement. Consider the following code:
$sth=$dbh->prepare("INSERT INTO mytable(a,b,c) SELECT ?,B(?),C(?)");
$sth->execute($a,$a,$a);
It would be very nice to instead use something like this:
#I'm making this up as something I hope exists
$sth=$dbh->prepare("INSERT INTO mytable(a,b,c) SELECT ?,B(?:1),C(?:1)");
$sth->execute($a);
Notice that only one $a is passed to the execute instead of three. Is there a way to do this in real life?
It depends on your DBD. For example, using DBD::Pg with the $1 style of placeholders, or DBD::Oracle with named placeholders and bind_param, you can do exactly what you like. But using the general purpose ? style of placeholders that works DBI-wide, it's not possible.
If you use a library to generate your SQL statements for you, e.g. SQL::Abstract or a full-on ORM like DBIx::Class, you won't have to worry about things like that.
Alternatively you can do something similar with just a few lines of code:
my $sql = 'INSERT INTO ...blah blah... VALUES (' . (join(', ', ('?') x scalar(#insert_elements))) . ')';
#hobbs' answer is right -- default DBI placeholders can't do it. #Ether's answer is right -- a SQL abstraction can make this a non-issue.
However, typically one need only bind each distinct parameterized value once. In your example, using a scalar derived table makes the user-supplied value available by name to the rest of the query:
my $sth = $dbh->prepare(<<'__eosql');
INSERT INTO mytable(a,b,c)
SELECT x, B(x), C(x) FROM (SELECT ? AS x) subq
-- Subquery may vary from DB to DB:
-- "FROM (SELECT ? AS x FROM DUAL) subq"
-- "FROM (SELECT ? FROM rdb$database) subq(x)"
-- "FROM (VALUES (?)) subq(x)"
-- etc.
__eosql
for $v (#values) {
$sth->execute($v);
}
Usually this is incrementally more "wire efficient" than the alternative, since the user-supplied parameter is typically transmitted just once instead of N times.
You can set SQL variables in one SQL statement and then use that variable multiple times in the next query.
$dbh->do('set #reusable = ?', undef, $perl_var);
$dbh->select_arrayref('select * from table where cola = #reusable or colb = #reusable');
No duplicated variables and you still get the safety of parameterized queries.