Known depth and edges query efficency - orientdb

My data looks like this:
a ---> b ---> c
a, b and c are vertices, there is one a, but multiple b-s and c-s (tree structure).
My a ---> b edge is of one class (let's call it ab class), while the b ---> c edge is another (bc class).
I need a query which will, given the name of a, produce x number of c-s.
So far, I found that this works:
select expand(set(out("ab").out("bc"))) from a where name='aName' limit x
Questions:
Can this query be improved?
How can I only select, for example, names of c-s, and not the whole records?
Thanks for your help!

I believe that query can only be improved if you define an index on A.name property.
About your second question:
create class A extends V
create class B extends V
create class C extends V
create class AB extends E
create class BC extends E
create vertex A set name = 'aName'
create vertex B set name = 'bName0'
create vertex B set name = 'bName1'
create vertex C set name = 'cName0'
create vertex C set name = 'cName1'
create vertex C set name = 'cName2'
create vertex C set name = 'cName3'
create edge AB from (select from A where name = 'aName') to (select from B where name = 'bName0')
create edge AB from (select from A where name = 'aName') to (select from B where name = 'bName1')
create edge BC from (select from B where name = 'bName0') to (select from C where name = 'cName0')
create edge BC from (select from B where name = 'bName0') to (select from C where name = 'cName2')
create edge BC from (select from B where name = 'bName1') to (select from C where name = 'cName1')
create edge BC from (select from B where name = 'bName1') to (select from C where name = 'cName3')
These queries may help you:
select from (select expand(out("AB").out("BC").include('name')) from A where name = 'aName') limit 3
// or
select name from (select expand(out("AB").out("BC")) from A where name = 'aName') limit 3

Related

Recursive query in DB for z/OS

Dear all I have a source table named "PROGRAM" as below
Program CSECT
X Y
B X
M P
A L
B D
C D
A C
B C
A B
D B
Given a Program say for example 'A' I need to find all the associated CSECTs
Program CSECT
A L
A C
A B
B D
B X
X Y
I have tried with recursive queries as below but it loops for a circular reference example B-D and D-B
WITH RPL (Program, Csect) AS
(SELECT ROOT.Program, ROOT.Csect
FROM Program ROOT
WHERE Program = 'A'
UNION ALL
SELECT CHILD.Program, CHILD.Csect
FROM RPL PARENT, Program CHILD
WHERE PARENT.Csect = CHILD.Program)
SELECT *
FROM RPL;
You may add and additional column (Chain) which would contain full path for the current row like below. A new row shouldn't be added, if CHILD.Program is already contained in such a path.
WITH RPL (Program, Csect, Chain) AS
(
SELECT ROOT.Program, ROOT.Csect, CAST('|' || ROOT.Program || '|' AS VARCHAR(1000))
FROM Program ROOT
WHERE Program = 'A'
UNION ALL
SELECT CHILD.Program, CHILD.Csect, PARENT.Chain || CHILD.Program || '|'
FROM RPL PARENT, Program CHILD
WHERE PARENT.Csect = CHILD.Program
AND LOCATE('|' || CHILD.Program || '|', PARENT.Chain) = 0
)
SELECT DISTINCT Program, Csect
FROM RPL
ORDER BY Program;

how to use update with join condition on 3 tables in postgresql

UPDATE patient
SET p.patient_name='Keerthi',
c.pat_cnt_pincode=560765
FROM patient as p
left JOIN patient_contact AS c on c.pat_cnt_email_id=p.patient_email
WHERE p.patient_id=921;
You can only update one table in a single statement. But, you could do:
with p as (
update patient p
set patient_name = 'Keerthi'
where p.patient_id = 921
returning *
)
update patient_contact pc
set pat_cnt_pincode = 560765
from p
where pc.pat_cnt_email_id = p.patient_email;

JPQL: Access to outer attributes in JOIN of subquery

In my JPA model there are 3 tables A, B, C.
My query is:
SELECT a FROM A a
WHERE EXISTS (
SELECT c from C c LEFT JOIN B b"
ON c = b.c AND b.a = a
WHERE c.date BETWEEN CURRENT_TIMESTAMP AND :pUntil AND b.a IS NULL
)
Background is that I want all entities of A that do not have an entry in b that is linked to an event C in the future.
The problem is that I get Column 'T0.ID' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or ...
EDIT
: Think of it as A is a user table, C are events, and B stores the registrations of users for events. I want to get all users, which have not registered for all future events until parameter pUntil.
Although I agree with Neil, I worked around this issue by changing my query. Here's the new query:
SELECT a FROM A a
WHERE EXISTS (
SELECT c from C c
WHERE c.date BETWEEN CURRENT_TIMESTAMP AND :pUntil
AND NOT EXISTS (
SELECT b from B b
WHERE b.c= c and b.a = a
)
)

Get field value from a record that causes an aggregate condition to be true

I have a table x which have the fields a, b, c, and d. I want to do a SELECT statement which is GROUPED BY a HAVING a_particular_value = ANY(array_agg(b)) and retrieves a, MIN(d), and c <- from which row is chosen by a_particular_value = ANY(array_agg(b)).
It's a bit confusing.
Lemme try to explain. a_particular_value = ANY(array_agg(b)) will choose some or one record from all records that is grouped by a. I want to retrieve the value of c from the record that causes the condition to be true. While NOT filter out other records because I still need those for the other aggregate function, MIN(d).
The query that I've tried to make:
SELECT a, MIN(d) FROM x
GROUP BY a
HAVING 1 = ANY(array_agg(b))
The only thing that's left to do is put c in the SELECT clause. How do I do this?
with agg as (
select a, min(d) as d
from x
group by a
having 1 = any(array_agg(b))
)
select distinct on (a, c)
a, c, d
from
x
inner join
agg using (a, d)
order by a, c
If min(d) is not unique within the a group then it is possible to exist more than one corresponding c. The above will return the smallest c. If you want the biggest do in instead
order by a, c desc
c can have various values in this scenario, so your only option is to group by c as well.
SELECT a, c FROM x
GROUP BY a, c
HAVING 1 = ANY(array_agg(b))
If you want to eliminate rows with b not satisfying condition before applying GROUP BY then use WHERE as documentation for HAVING says http://www.postgresql.org/docs/9.2/static/sql-select.html#SQL-HAVING

Using Aggregate functions in JPA

I have the folowing situation.
I want to retrieve a list of bids between time t1 and time t2. Then from this list i want to retrieve winning bid i.e maximum bid price.
I have written the following JPA query.
SELECT b FROM Bid b WHERE b.bidAmt = (SELECT MAX(b.bidAmt) FROM b WHERE b.lastUpdtTs BETWEEN ?1 AND ?2)
But I am getting the following exception.
Exception Description: Syntax error parsing the query [SELECT b FROM Bid b WHERE b.bidAmt = (SELECT MAX(b.bidAmt) FROM b WHERE b.lastUpdtTs BETWEEN ?1 AND ?2)], line 1, column 64: unexpected token [b].
Internal Exception: NoViableAltException(66!=[1108:1: subselectIdentificationVariableDeclaration[List varDecls] : ( identificationVariableDeclaration[varDecls] | n= associationPathExpression ( AS )? i= IDENT | n= collectionMemberDeclaration );])
Couls someone point out the mistake?
Since you query references two different Bid instances, they should have different aliases:
SELECT b FROM Bid b WHERE b.bidAmt =
(SELECT MAX(bb.bidAmt) FROM Bid bb WHERE bb.lastUpdtTs BETWEEN ?1 AND ?2)
Haven't tried it myself, but from what I see, mistake could be in your subquery. You say FROM b, but it should be FROM Bid b. So, the entire query looks like this:
SELECT b FROM Bid b WHERE b.bidAmt = (SELECT MAX(b.bidAmt) FROM Bid b WHERE b.lastUpdtTs BETWEEN ?1 AND ?2)
The Error you got the second time is
multiple declaration of identification
variable [b], previously declared as
[Bid b]
From the above error it seems like b alias declared for multiple times so remove alias b from sub query
try out following query
SELECT b FROM Bid b WHERE b.bidAmt =
(SELECT MAX(bidAmt) FROM Bid WHERE lastUpdtTs BETWEEN ?1 AND ?2)