What's the opposite of the intersect function in OrientDB? - orientdb

I'm currently looking for the opposite of the function intersect
Let me explain with some queries :
the first one return a list of #rid
The seconde one retun a list of #rid
The third one return a list of #rid which are in the first and in the second one
-> I'm looking for the query that return a list of #rid which are in the first but not in the second
SELECT in("Regroupe").in("Obligatoire").out("Pertinent") FROM 89:50
-> #69:110 #62:19 #60:1 #59:38 #62:114
SELECT out("Pertinent") FROM 89:50
-> #69:110 #62:19 #60:1
SELECT intersect(in("Regroupe").in("Obligatoire").out("Pertinent"), out("Pertinent")) FROM #89:50
-> #62:19 #60:1 #69:110
I'm looking for this query :
SELECT except/difference(in("Regroupe").in("Obligatoire").out("Pertinent"), out("Pertinent")) FROM #89:50
-> #59:38 #62:114

Ok i find what was missing !
I have to compare on #rid :
SELECT difference(in("Regroupe").in("Obligatoire").out("Pertinent").#rid, out("Pertinent").#rid) FROM #89:50

Related

OrientDB query all out edges

I want to do a query in OrientDB but i don't know how it works.
I'm using the Graph API and my DB looks like this:
class(V): #route (Name, Start, Length, Goal)
class(V): #direction (Goal, length)
class(E): #has_A
class(E): #start_Direction
class(E): #has_Follower
The Edges are connected to the Vertices like this:
route -> has_A -> direction
route -> start_Direction -> direction
direction -> has_Follower -> direction
now i need to find all followers by the name of the route,
what works so far is when i enter a rid (of the class startDirection) directly to the query for example:
select * from (traverse outE('has_Follower'),has_Follower.in from #??:?) where #class='direction'
But now i need to get to the rid over the Name of the route (which is the problem), what i tried so far is:
select * from (traverse outE('has_Follower'),has_Follower.in from (select #rid from start_Direction where start_Direction.out = (select #rid from route where Name = 'nameOfroute'))) where #class='direction'
But this gives me an empty query, although when i type in the rid from start_Direction of which i know has a has_Follower it works.
Hope this is understandable, thanks for any help in advance.
One problem in your query is probably start_Direction.out = (select..., you have to use an IN instead of an =, eg start_Direction.out IN (select....
In general, I think the easiest way to do what you need is as follows:
MATCH
{class:route, as:route} -start_Direction-> {} -has_Follower-> {as:direction, while:(true)}
RETURN route.#rid, route.Name, route.Start, route.Length, route.Goal, direction.Goal, direction.length
Or just RETURN $elements if you want single records per row

Using functions with orientdb select query with edge filter

Schema
Customer -> (Edge)Ownes -> Vehicle {vehicle_number}
tried to query the customer record who "Ownes" a vehicle by its number like below and it worked. (both 'in' and 'contains' worked fine)
select from Customer where "KL-01-B-8898" in out("Ownes").vehicle_number
I want to do the same query but using a case insensitive search, like below, but returned '0' records
select from Customer where "kl-01-b-8898" in out("Ownes").vehicle_number.toLowerCase()
I changed the query like below and it returned the rows. Is it possible to use functions like 'toLowerCase' in the queries like above, with out sub select ?
select from Customer where #rid in (select in("Ownes").#rid from Vehicle where vehicle_number.toLowerCase() ="kl-01-b-8898")
You can use this:
select from Customer
let $a= ( select number.toUpperCase() from (select out("Ownes").vehicle_number as number from $parent.$current unwind number))
where "KL-01-B-8898" in first($a).number
This doesn't work:
select from Customer where "kl-01-b-8898" in out("Ownes").vehicle_number.toLowerCase()
because
out("Ownes").vehicle_number
return a list of String
This works:
select from Customer where #rid in (select in("Ownes").#rid from Vehicle where vehicle_number.toLowerCase() ="kl-01-b-8898")
because vehicle_number is a String
See the documentation: http://orientdb.com/docs/last/SQL-Methods.html#bundled-methods

Processing record type from a jsonb_each query

I store some data as JSON.
I want to flatten the data using jsonb_each.
The new column type is RECORD, but I don't how extract values from it.
SELECT T FROM (
SELECT json_each_text(skills::json->'prizes') FROM users) AS T;
The output is
jsonb_each
---------------------------------
(compliance,2)
(incentives,3)
(compliance,0)
(legal,3)
(legal,2)
(international-contributions,3)
The type is RECORD.
pg_typeof
-----------
record
I want to do an aggregate and GROUPBY, but I cannot figure out how to extract the first element(the string) and the second element (the value).
Here is a workaround I have found: JSON -> ROW -> JSON -> (string, integer) and then aggregate. But I am wondering if there is a shortcut and skip the ROW->JSON conversion.
SELECT U.key, AVG(U.value::int) FROM
(SELECT row_to_json(T)->'s'->>'key' AS key,
row_to_json(T)->'s'->>'value' AS value
FROM
(SELECT jsonb_each(skills::jsonb->'prizes') AS s
FROM users) AS T
) AS U
GROUP BY key;
Thanks a lot, #Arnaud, this seems like a not-very-common problem. I wasn't sure about json data structure after using row_to_json function, so I needed to validate that via:
SELECT row_to_json(T) FROM
(SELECT jsonb_each((data->'app_metadata'->>'results')::jsonb)
FROM temp) AS T;
And once I got the keys structure, I could replicate your approach:
SELECT row_to_json(T)->'jsonb_each'->>'key' as key, row_to_json(T)->'jsonb_each'->>'value' as value
FROM (select jsonb_each((data->'app_metadata'->>'results')::jsonb) FROM temp) AS T

Error in update query

I have two entities STOCK(name,amount) and PC_SYSTEMS(name,c_name), and i wish to update the components needed to create the PC_system "Alienware", therefore i want it to subtract 1 from the amount of the components, needed to create the alienware system, in Stock.
Here's my query:
"UPDATE stock SET amount=amount-1 WHERE name = ( SELECT p.c_name FROM pc_systems p WHERE p.name='Alienware');"
I get a weird error that says:
" more than one row returned by a subquery used as an expression"
Would be happy if someone could help.
Edit:
I SOLVED this by putting an "IN" in my query instead of "=". Final code:
UPDATE stock SET amount=amount-1 WHERE name IN ( SELECT p.c_name FROM pc_systems p WHERE p.name='Alienware');
What it means is this SQL returns more than 1 row. Make it so it returns exactly 1 row only.
SELECT p.c_name FROM pc_systems p WHERE p.name='Alienware'
Since your subquery is returning more than one record you cannot use that syntax. try something like this:
UPDATE S
SET S.amount=S.amount-1
FROM Stock S
INNER JOIN pc_systems p
ON S.name = p.c_name
WHERE p.name='Alienware'
or try this:
update stock
set s.amount=s.amount-1
from stock s
inner join pc_systems p on S.name = p.c_name
where p.name='Alienware'

Table scoping difficulty: Joining on a sub query with a where clause from a table outside the subquery

I am trying to adapt a stored procedure into a view and I've run into what appears to be a table scoping issue in SQL Server 2008 R2.
In the sproc, there was a parameter that specified the companyId. Now we want to retrieve the same data but not limit it to a specific companyId but rather to group by that companyId.
However, my attempt broadening it has failed.
Select Distinct [T].[TruckID], [T].[VIN], [T].[Make], [T].[Model],
[T].[ModelYear], [T].[RFIDNo], [SQCT].[VendorCode], [SQCT].[UserLabel],
[T].[IsActive], [T].[IsFleetTruck], [SQDA].[DriverAssociations],
dbo.GetCurrentPlate([T].[TruckID]) [Plate],
[TCT].[CompanyId] -- // <- Now we're including it
From [dbo].[Truck] as [T]
Inner Join [dbo].[TruckerCompanyTruck] as [TCT]
On [T].[TruckID] = [TCT].[TruckId]
Left Outer Join (
Select [CT].[CompanyTruckId], [CT].[CompanyId],
[CT].[TruckId], [CT].[VendorCode], [CT].[UserLabel],
[CT].[CreateDate], [CT].[CreateBy], [CT].[UpdateDate],
[CT].[UpdateBy], [CT].[Version]
From [dbo].[CompanyTruck] as [CT]
) as [SQCT]
On [TCT].[CompanyId] = [SQCT].[CompanyId]
and [TCT].[TruckId] = [SQCT].[TruckId]
Left Join (
Select Distinct [TCTC].[TruckId], Count(*) [DriverAssociations]
From [TruckerCompanyTruck] [TCTC]
Inner Join [Trucker] [D]
On [TCTC].[TruckerId] = [D].[TruckerId]
Inner Join [TruckerContract] [TC]
On [TCTC].[TruckerId] = [TC].[TruckerId]
Where [TCTC].[CompanyId] = [TCT].[CompanyId] -- // Error!
and [TC].[CompanyId] = [TCT].[CompanyId] -- // Error!
Group By [TCTC].[TruckId]
) as [SQDA]
On [SQDA].[TruckId] = [T].[TruckId]
The "Error!" lines throw "The multi-part identifier "TCT.CompanyId" could not be bound."
The ultimate goal is that running this query will produce multiple rows for a truck that has multiple company associations and return the correct driver count.
In the end, this query of the view...
Select *
From [FlattenedTruck]
Where [CompanyId] = 28
Order By [VIN]
...should produce the same output as this.
Exec [GetTrucksForGridWithAssociationCounts] #companyId = 28
But the differ. The sproc returns 1 driver association for companyId 28 and the view returns 1246 driver associations which is all of the associations for that truck regardless of the company. (It's also different because the sproc does not return the companyId because it's passed in as a parameter.)
TruckID -> VIN -> Make -> Model -> ModelYear -> RFIDNo -> VendorCode -> UserLabel -> IsActive -> IsFleetTruck -> DriverAssociations -> Plate -> CompanyId
26 -> NULL -> NULL -> NULL -> NULL -> NULL -> NULL -> NULL -> 1 -> 0 -> 1246 -> US-WA-9D68812 28
26 -> NULL -> NULL -> NULL -> NULL -> NULL -> NULL -> NULL -> 1 -> 0 -> 1 -> US-WA-9D68812
Can you try OUTER APPLY instead of the LEFT JOIN to the SQDA subquery? You'll want to add the condition of [TCTC].[TruckId] = [T].[TruckId] to the WHERE clause within the subquery, as the APPLY doesn't take an ON condition.
When joining with subqueries, it is important to remember that joins inside the subquery are not aware of tables joined outside the subquery.
The error is being thrown because you are attempting to reference table TCT inside the parentheses of the SQDA subquery, but the join aliased to TCT is outside the parentheses. You are joining that same table inside the parentheses as TCTC so it is a simple matter of changing any use of TCT inside the subquery to TCTC, or moving it outside as appropriate.
So your WHERE clause would become WHERE [TC].[CompanyId] = [TCTC].[CompanyId] inside the subquery, and you would move the other clause outside to join to the subquery since WHERE [TCTC].[CompanyId] = [TCTC].[CompanyId] is pointless,
That will make the query work; without knowing more about the underlying data model I can't guarantee it will actually return what you intend it to return. But that should be sufficient to get you past the error you are currently getting.