Querying Out from Out in OrienDB? - orientdb

Looking at the following image:
I need a query that just outputs four rows as below:
A1.SomeProperty, B1.SomeProperty, C1.SomeProperty
A1.SomeProperty, B1.SomeProperty, C2.SomeProperty
A1.SomeProperty, B2.SomeProperty, C3.SomeProperty
A1.SomeProperty, B2.SomeProperty, C4.SomeProperty
I have tried the following:
SELECT
SomeProperty as A_Property
out(L1).SomeProperty as B_Property,
out(L1).out(L2).SomeProperty as C_Property
from A
UNWIND B_Property, C_Property
I can't get my head around UNWIND - I think the problem is following out(L1) and out(L2).

Getting closer thanks to Luigi.
Need to get other properties from "Result" without unwiding
SELECT
a.A_Property as ID,
b.B_Property as Name,
b.out(Link).C_Property as Result
FROM
(MATCH
{class:A, as:a} --> {optional:true, as:b}
RETURN
a,b)
UNWIND Result

If you are on v 2.2 you can use MATCH statement:
MATCH
{class:A, as:a} -L1-> {as:b} -L2-> {as:c}
RETURN
a.SomeProperty as A_Property,
b.SomeProperty as B_Property,
c.SomeProperty as C_Property
If you also need the edges:
MATCH
{class:A, as:a} .outE("L1"){as:edge1}.inV() {as:b} .outE("L2"){as:edge2}.inV() {as:c}
RETURN
a.SomeProperty as A_Property,
b.SomeProperty as B_Property,
c.SomeProperty as C_Property,
edge1.something as xxx,
edge2.something as yyy

Related

Postgresql, how to SELECT json object without duplicated rows

I'm trying to find out how to get JSON object results of selected rows, and not to show duplicated rows.
My current query:
SELECT DISTINCT ON (vp.id) jsonb_agg(jsonb_build_object('affiliate',a.*)) as affiliates, jsonb_agg(jsonb_build_object('vendor',vp.*)) as vendors FROM
affiliates a
INNER JOIN related_affiliates ra ON a.id = ra.affiliate_id
INNER JOIN related_vendors rv ON ra.product_id = rv.product_id
INNER JOIN vendor_partners vp ON rv.vendor_partner_id = vp.id
WHERE ra.product_id = 79 AND a.is_active = true
GROUP BY vp.id
The results that I receive from this is:
[
affiliates: {
affiliate: affiliate1
affiliate: affiliate2
},
vendors: {
vendor: vendor1,
vendor: vendor1,
}
As you can see in the second record, vendor is still vendor1 because there are no more results, so I'd like to also know if there's a way to remove duplicates.
Thanks.
First point : the result you display here above doesn't conform the json type : the keys are not double-quoted, the string values are not double-quoted, having dupplicated keys in the same json object ('{"affiliate": "affiliate1", "affiliate": "affiliate2"}' :: json) is not be accepted with the jsonb type (but it is with the json type).
Second point : you can try to add the DISTINCT key word directly in the jsonb_agg function :
jsonb_agg(DISTINCT jsonb_build_object('vendor',vp.*))
and remove the DISTINCT ON (vp.id) clause.
You can also add an ORDER BY clause directly in any aggregate function. For more information, see the manual.
You could aggregate first, then join on the results of the aggregates:
SELECT a.affiliates, v.vendors
FROM (
select af.id, jsonb_agg(jsonb_build_object('affiliate',af.*)) as affiliates
from affiliates af
group by af.id
) a
JOIN related_affiliates ra ON a.id = ra.affiliate_id
JOIN related_vendors rv ON ra.product_id = rv.product_id
JOIN (
select vp.id, jsonb_agg(jsonb_build_object('vendor',vp.*)) as vendors
from vendor_partners vp
group by vp.id
) v ON rv.vendor_partner_id = v.id
WHERE ra.product_id = 79
AND a.is_active = true

OrientDB - expand() with additional fields

Starting from the following query:
MATCH
{class: MYCLASS}-->{as: a}-->{as: b}
RETURN
$matches
which returns:
PROPERTIES
=============
a | b
-------------
#25:0 | #10:0
#25:0 | #9:0
#29:0 | #11:0
#29:0 | #33:0
I want all the fields from b and the class of a returned. Also I don't know what fields are in b.
Basically this:
SELECT
expand(b), a.#class
FROM
(MATCH
{class: MYCLASS}-->{as: a}-->{as: b}
RETURN
$matches)
;
which of course returns the error message: Cannot execute a query with expand() together with other projections DB name="test"
Any help would be appreciated.
Try this:
select $a as b, $b.a_class as class
let $a = (select expand(b) from (MATCH {class: MYCLASS}-->{as: a}-->{as: b} RETURN $matches)),
$b = (select a.#class as a_class from (MATCH {class: MYCLASS}-->{as: a}-->{as: b} RETURN $matches))
unwind class
This is what you get:
Hope it helps
Regards
#Michela Bonizzi though your answer didn't gave me the exact result I wanted it gave me a new idea
SELECT
*, in().#class as a_class
FROM
(MATCH
{class: BEWERTUNG}-->{as: a}-->{as: b}
RETURN
expand(b))
UNWIND a_class
queryresult

How to correctly use the querybuilder in order to do a subselect?

I would like to do a subselect in order to do the following postgresql query with the querybuilder:
SELECT i.* FROM internship i
WHERE EXISTS (SELECT iw.*
FROM internship_weeks iw
WHERE i.id = iw.internship)
Does anyone have an idea how to get the same result with queryBuilder? or maybe with DQL?
Thanks for the help !
As example, only for demonstrate HOW-TO use a subquery select statement inside a select statement, suppose we what to find all user that not yet have compile the address (no records exists in the address table):
// get an ExpressionBuilder instance, so that you
$expr = $this->_em->getExpressionBuilder();
// create a subquery
$sub = $this->_em->createQueryBuilder()
->select('iw')
->from(IntershipWeek::class, 'iw')
->where('i.id = iw.intership');
$qb = $this->_em->createQueryBuilder()
->select('i')
->from(Intership::class, 'u')
->where($expr->exists($sub->getDQL()));
return $qb->getQuery()->getResult();
Hope this help

Filtering query using outE() with EmbeddedMap

I have a vertex as below.
And I also have an edge (it is an out edge of above vertex) as below.
I can query with following SQL statements.
select from #20:6 where outE().weight in 1
select from #28:12 where sessionStatus.keys() in "session1"
However when I combined the 2 filters above, there is no vertex out from the query.
select from #20:6 where outE().sessionStatus.keys() in "session1"
Is there anyone guide me the correct filter I can use?
you can use MATCH
select expand(vv) from (
MATCH
{
class: GW_Score,
as: vv,
where: (#rid=20:6)
}
.outE(){
as: ee,
where: (sessionStatus.keys() = "session1")
}
RETURN vv
)
Try with this query:
select from #20:6 where ["session1"] in outE()[0].sessionStatus.keys()
Hope it helps.

SQL Between Alphanumeric value

I have an Alphanumeric column in my db table. For my filter, I was using between to get the result filter value. Everything is okay. But, In some cases it misses some of the data's from filtering. Here are my samples,
Sample data
ACQPO14
002421
ACQPO8
ACQPO14
ACQPO19
DUMMY0001
Sql Query
SELECT po.No,
po.PoS
FROM PoDetails pod
INNER JOIN Pors po ON po.Id=PoD.PoId
WHERE po.No BETWEEN 'ACQPO1' AND 'ACQPO20'
For the above sample. the query returns only ACQPO14 and ACQPO19 NOT ACQPO8.
Any help to this issue will be appreciated.
Thanks
It makes sense as it is just text.
1 comes before 8 so, ordering in text (left to right) the db will disregard the last digit of ACQPO14 to compare it against ACQPO8. So ACQPO1 (4 removed) comes before ACQPO8 and ACQPO2 (0 removed) comes before ACQPO8 as well. So it gets filtered out by the between.
The only way for you to fix this is to parse the column by splitting it. EG: If ACQPO is a fixed-length prefix you can use some DBMS function (you haven't specified any) to trim that part and turn into a numeric format the rest. Then compare/filter by that numeric remainder.
This is how you would do this in Oracle
SELECT po.No, po.PoS
FROM PoDetails pod
INNER JOIN Pors po ON po.Id=PoD.PoId
WHERE SUBSTR(po.No, 1, 5) = 'ACPQO'
AND TO_NUMBER(SUBSTR(po.No, 6, 2)) >= 1
AND TO_NUMBER(SUBSTR(po.No, 6, 2)) <= 20;
First SUBSTR() is used to match the textual part of the value. Then the numeric part of the values is parsed into a number using TO_NUMBER() and made available for numeric comparison between 1 and 20. (Other databases would also have similar functions to do the same.)
If ACQPO is fixed then try below in SQL Server
SELECT po.No, po.PoS
FROM PoDetails pod
INNER JOIN Pors po ON po.Id=PoD.PoId
WHERE left(po.No,5) and
cast(substring(po.No,6,len(po.No)) as int)
BETWEEN cast(substring('ACQPO1',6,len(po.No)) as int) AND cast(substring('ACQPO20',6,len(po.No)) as int)
SELECT substring(data,6,len(data)),* FROM #Temp Where
left(data,5) ='ACQPO' And
cast(substring(data,6,len(data)) as int)
BETWEEN cast(substring('ACQPO1',6,len(data)) as int) AND cast(substring('ACQPO20',6,len(data)) as int)
FOR MYSQL:-
SELECT * FROM my_table WHERE
SUBSTR(seq_num, 1,3) = 'ABC' /* verifying prefix code */
AND
REPLACE(seq_num, 'ABC', '') >= 61440
AND
REPLACE(seq_num, 'ABC', '') <= 61807
OR
SELECT * FROM my_table WHERE
SUBSTR(seq_num, 1,3) = 'ABC' /* verifying prefix code */
AND
substr(seq_num, 4, length(seq_num)) >= 61440
AND
SUBSTR(seq_num, 4, LENGTH(seq_num)) <= 61807
works for (like) :
ABC61447,
ABC61448,
ABC61545,
...,
...,
ABC61807
Just use range 10 to 20 and it works!
SELECT po.No,
po.PoS
FROM PoDetails pod
INNER JOIN Pors po ON po.Id=PoD.PoId
WHERE po.No BETWEEN 'ACQPO10' AND 'ACQPO20'