Convert a complex relational SQL query so that it runs in OrientDB - sql

I am a newbie to OrientDB. I have a table structure as shown below. I have tried out a lot of queries but still cannot figure out how to implement the following SQL query in OrientDB. I need to join data from 4 different classes. Any help is greatly appreciated.
select Users.Name as uName,
Shops.Name as shopName,
ShopTotalPurchases.Total
from Users, Shops, Purchases,ShopTotalPurchases
where Users.Id=10
and Purchases.UserId=Users.Id
and Purchases.Date="date2"
and ShopTotalPurchases.Date="date2"
and ShopTotalPurchases.ShopId = Shops.Id
> reldb> SELECT * FROM Users;
+----+--------+-------+
| Id | Name | Phone |
+----+----------------+
| 10 | User 1 | 1111 |
+----+----------------+
| 20 | User 2 | 2222 |
+----+----------------+
> reldb> SELECT * FROM Shops;
+----+--------+-------+
| Id | Name | Phone |
+----+----------------+
| 30 | Shop 1 | 1111 |
+----+----------------+
| 40 | Shop 2 | 2222 |
+----+----------------+
> reldb> SELECT * FROM Purchases; [unique per combo of UserId, ShopId and Date]
+----+--------+--------+--------+------+-----------+
| Id | UserId | Item | ShopId | Date | ItemPrice |
+----+--------+-----------------+------+-----------+
| 0 | 10 | First | 30 |date1 | 100 |
+----+--------+--------+--------+------+-----------+
| 1 | 10 | Second | 30 |date2 | 200 |
+----+--------+--------+--------+------+-----------+
| 21 | 10 | Third | 40 |date3 | 300 |
+----+--------+--------+--------+------+-----------+
| 41 | 20 | Fourth | 40 |date4 | 400 |
+----+--------+--------+--------+------+-----------+
| 82 | 20 | Fift | 30 |date5 | 500 |
+----+--------+--------+--------+------+-----------+
> reldb> SELECT * FROM ShopTotalPurchases;
+----+--------+--------+------+
| Id | Total | ShopId | Date |
+----+--------+--------+------+
| 0 | 1000 | 30 |date1 |
+----+--------+--------+------+
| 1 | 2000 | 30 |date2 |
+----+--------+--------+------+
| 21 | 3000 | 40 |date2 |
+----+--------+--------+------+

you can use this query:
select $a.Name as uName, $b.Name as shopName, $c.Total as Total from Purchases
let $a = (select Name from User where Id = 10 and Id in $parent.current.UserId),
$b = (select Name from Shops where Id in $parent.current.ShopId),
$c = (select Total from ShopTotalPurchases where Date = 'date2' and ShopId in $parent.current.ShopId)
where Date = 'date2' unwind uName, shopName, Total
Console output:
----+------+-----+--------+------
# |#CLASS|uName|shopName|Total
----+------+-----+--------+------
0 |null |User1|Shop1 |2000.0
----+------+-----+--------+------

Related

how to sum a column of a queried table in sql

I have this table from a query and I would like to find the sum of the Total Cost (after discount). I have searched for a solution but I can't seem to find the one I'm looking for.
Here are the sample data from my tables
Booking
+-----------+-------------+----------+------------+
| vehicleNo |  bookingDay | driverNo | acc_status |
+-----------+-------------+----------+------------+
| 10 | 13/06/2021 | 2 | B |
| 10 | 14/06/2021 | 0 | B |
| 10 | 15/06/2021 | 2 | B |
| 20 | 17/06/2021 | 2 | B |
+-----------+-------------+----------+------------+
Vehicle
+-----------+-------------+----------------+------+
| vehicleNo |  vehicleReg | make_model | cost |
+-----------+-------------+----------------+------+
| 10 | IN10NGT | Nissan R34 GTR | 90 |
| 20 | IN10MRX | Mazda RX7 | 70 |
| 30 | IN10TSU | Toyota Supra | 80 |
+-----------+-------------+----------------+------+
Here is the query
SELECT IF(COUNT(Vehicle.vehicleNo) > 1, ROUND(Vehicle.cost,1) * ROUND(COUNT(Vehicle.vehicleNo) * 0.9,1), Vehicle.cost * ROUND(COUNT(Vehicle.vehicleNo),1)) AS 'Total after discount'
FROM Booking
INNER JOIN Vehicle
ON Vehicle.vehicleNo = Booking.vehicleNo
WHERE Booking.driverNo = 2
GROUP BY Vehicle.vehicleNo
ORDER BY Vehicle.vehicleNo;
an here is the result
+----------------------+
| Total after discount |
+----------------------+
| 162 |
| 70 |
+----------------------+
and I am expecting to have a table after calculating the sum like this
+----------------------+
| Overall cost |
|after discount |
+----------------------+
| 232 |
+----------------------+
any help is much appreciated.
i have figured it out. i used this query:
SELECT SUM(Cost) FROM (SELECT IF(COUNT(Vehicle.vehicleNo) > 1, ROUND(Vehicle.cost,1) * ROUND(COUNT(Vehicle.vehicleNo) * 0.9,1), Vehicle.cost * ROUND(COUNT(Vehicle.vehicleNo),1)) AS Cost
FROM Vehicle INNER JOIN Booking
ON Vehicle.vehicleNo = Booking.vehicleNo AND Booking.driverNo = 2
GROUP BY Vehicle.vehicleNo) AS x;

SQL query for the store with the minimum price of an item in the city

I have this table
(city,storeID,itemID,price)
I need to return for each city,itemID the storeID with the minimum price for the item and the minimum price itself ( city,itemID,storeIDmin,minprice).
Can someone help me with this query ?
Thanks!
I solved this with Join and Subquery (Also possible to use "WITH AS" Clause if you work on oracle DB):
SELECT table1.city, table1.itemID, table1.storeID as storeIDmin, subquery.min_price
FROM table1
JOIN (select city, itemID, min(price) as min_price from table1
group by city,itemID) AS subquery
ON table1.city = subquery.city
AND table1.itemID = subqueryitemID
AND table1.price =
subquery.min_price
the result for example:
+------+---------+--------+-------+
| city | storeID | itemID | price |
+------+---------+--------+-------+
| 1 | 1 | 1 | 70 |
| 1 | 2 | 1 | 60 |
| 2 | 1 | 1 | 100 |
| 2 | 1 | 2 | 90 |
| 2 | 2 | 1 | 88 |
| 3 | 1 | 1 | 70 |
+------+---------+--------+-------+
will result:
+------+--------+----------+-------+
| city | itemID | storeMin | price |
+------+--------+----------+-------+
| 2 | 1 | 1 | 88 |
| 3 | 1 | 1 | 70 |
| 2 | 2 | 1 | 90 |
| 1 | 1 | 2 | 60 |
+------+--------+----------+-------+
You can approach this with a correlated subquery:
select t.*
from t
where t.price = (select min(t2.price) from t t2 where t2.itemId = t.itemId);

Need query for JOIN four tables with some conditions?

I have the following four tables:
1) mls_user
2) mls_category
3) bonus_point
4) mls_entry
In mls_user table values are like below:
*-------------------------*
| id | store_id | name |
*-------------------------*
| 1 | 101 | sandeep |
| 2 | 101 | gagan |
| 3 | 102 | santosh |
| 4 | 103 | manu |
| 5 | 101 | jagveer |
*-------------------------*
In mls_category table values are like below:
*---------------------------------*
| cat_no | store_id | cat_value |
*---------------------------------*
| 20 | 101 | 1 |
| 21 | 101 | 4 |
| 30 | 102 | 1 |
| 31 | 102 | 2 |
| 40 | 103 | 1 |
| 41 | 103 | 1 |
*---------------------------------*
In bonus_point table values are like below:
*-----------------------------------*
| user_id | store_id | bonus_point |
| 1 | 101 | 10 |
| 4 | 101 | 5 |
*-----------------------------------*
In mls_entry table values are like below:
*-------------------------------------------------------*
| user_id | store_id | category | distance | status |
*-------------------------------------------------------*
| 1 | 101 | 20 | 10 | Approved |
| 1 | 101 | 21 | 40 | Approved |
| 1 | 101 | 20 | 10 | Approved |
| 2 | 101 | 20 | 5 | Approved |
| 3 | 102 | 30 | 10 | Approved |
| 3 | 102 | 31 | 80 | Approved |
| 4 | 101 | 20 | 15 | Approved |
*-------------------------------------------------------*
And I want below output:
*--------------------------------------------------*
| user name | Points | bonus Point | Total Point |
*--------------------------------------------------*
| Sandeep | 30 | 10 | 40 |
| Santosh | 30 | 0 | 30 |
| Manu | 15 | 5 | 20 |
| Gagan | 5 | 0 | 5 |
| Jagveer | 0 | 0 | 0 |
*--------------------------------------------------*
I tell the calculation of how the points will come for user Sandeep.
Points = ((10+10)/1 + 40/4)=30
Here 1 and 4 is cat value which comes from mls_category.
I am using below code for a particular user but when i
SELECT sum(t1.totald/c.cat_value) as total_distance
FROM mls_category c
join (
select sum(distance) totald, user_id, category
FROM mls_entry
WHERE user_id=1 AND store_id='101' AND status='approved'
group by user_id, category) t1 on c.cat_no = t1.category
I have created tables in online for checking
DEMO
Computing the points (other than the bonus points) requires a separate join between the mls_entry and mls_category tables. I would do this in a separate subquery, and then join this to the larger query.
Here is one approach:
SELECT
u.name,
COALESCE(t1.points, 0) AS points,
COALESCE(b.bonus_point, 0) AS bonus_points,
COALESCE(t1.points, 0) + COALESCE(b.bonus_point, 0) AS total_points
FROM mls_user u
LEFT JOIN
(
SELECT e.user_id, SUM(e.distance / c.cat_value) AS points
FROM mls_entry e
INNER JOIN mls_category c
ON e.store_id = c.store_id AND e.category = c.cat_no
GROUP BY e.user_id
) t1
ON u.id = t1.user_id
LEFT JOIN bonus_point b
ON u.id = b.user_id
ORDER BY
total_points DESC;
This is the output I am getting from the above query in the demo you setup:
The output does not match exactly, because you have (perhaps) a typo in Santosh's data in your question, or otherwise the expected output in your question has a typo.

SQL SUM with Conditions

+--------+--------+-------+-------+
| PartId | ItemId | Price | Staus |
+--------+--------+-------+-------+
| 94669 | 3678 | 88 | 1 |
| 94669 | 3679 | 22 | 1 |
| 94669 | 3680 | 30 | 1 |
| 94669 | 3681 | 50 | 4 |
| 94670 | 3678 | 88 | 1 |
| 94670 | 3679 | 22 | 1 |
| 94670 | 3680 | 30 | 1 |
| 94670 | 3681 | 50 | 1 |
+--------+--------+-------+-------+
The expected output is (without status 4)
+--------+------------+
| PartId | TotalPrice |
+--------+------------+
| 94669 | 140 |
| 94670 | 190 |
+--------+------------+
How can I achieve this in SQL?
Pretty basic aggregation query with a where and group by.
select partid, sum(price) as totalprice
from t
where [status] <> 4
group by partid
If you have to omit status other than 1, it would be correct to use status = 1 instead:
select partid, sum(price) as totalprice
from t
where [status] = 1
group by partid
You can try:
SELECT "Part ID", SUM(Price)
FROM (
SELECT "Part ID", Price
FROM Table
WHERE Status <> 4)
GROUP BY "Part ID";

How to use SQL one to many relation joins with sub-query

I have created below query for report in SSRS 2008 R2 using matrix.
Please have a look at the below sample data and query.
=>Get the inc_id when the usr_id is reference into it in incident table.
=>In actions table, If any inc_id reference to another usr_id it will be skipped.
is there any changes need for the one to many relation in my query ? Please help
Table: incident
+--------+-------------+--------+---------+
| inc_id | date_logged | usr_id | dept_id |
+--------+-------------+--------+---------+
| 100 | 1-Aug-15 | 1 | 10 |
| 101 | 1-Sep-15 | 2 | 20 |
| 102 | 25-Aug-15 | 1 | 10 |
+--------+-------------+--------+---------+
Table:Actions
+--------+-----------+----------+--------------+--------+---------+
| inc_id | date_act | act_type | servicr_time | usr_id | dept_id |
+--------+-----------+----------+--------------+--------+---------+
| 100 | 2-Aug-15 | Travel | 300 | 1 | 10 |
| 100 | 3-Aug-15 | Remote | 200 | 3 | 30 |
| 100 | 5-Aug-15 | Travel | 200 | 1 | 10 |
| 100 | 10-Sep-15 | Travel | 250 | 1 | 10 |
| 101 | 1-Sep-15 | Travel | 150 | 2 | 20 |
| 101 | 1-Sep-16 | Travel | 120 | 3 | 30 |
| 102 | 29-Aug-15 | Travel | 150 | 1 | 10 |
| 102 | 30-Aug-15 | Remote | 120 | 1 | 10 |
+--------+-----------+----------+--------------+--------+---------+
Query:
SELECT COUNT(distinct inc.inc_id) AS [inc_count],
inc.inc_id,
DATEPART(YEAR, a.date_act) 'act_year',
DATENAME(MONTH, a.date_act) 'act_month',
inc.dept_id, inc.usr_id,
(
SELECT ISNULL(SUM(ac.service_time), 0) AS Expr1
FROM actions as ac
WHERE (ac.act_type IN ('Travel Time'))
AND (ac.inc_id = inc.inc_id)
AND (DATEPART(YEAR, ac.date_act) = DATEPART(YEAR, a.date_act))
AND (DATENAME(MONTH, ac.date_act) = DATENAME(MONTH, a.date_act))
AND ac.date_act BETWEEN '2015-08-01' AND DATEADD(day, 1, '2015-09-30')
) / 60 AS [Travel_Time],
(
SELECT ISNULL(SUM(ac.service_time), 0) AS Expr1
FROM actions as ac
WHERE (ac.act_type IN ('Remote'))
AND (ac.inc_id = inc.inc_id)
AND (DATEPART(YEAR, ac.date_act) = DATEPART(YEAR, a.date_act))
AND (DATENAME(MONTH, ac.date_act) = DATENAME(MONTH, a.date_act))
AND ac.date_act BETWEEN '2015-08-01' AND DATEADD(day, 1, '2015-09-30')
) / 60 AS [Remote_Time]
FROM incident AS inc
INNER JOIN inc_data as id ON inc.inc_id = id.inc_id
INNER JOIN actions as a ON a.inc_id = inc.inc_id
WHERE a.dept_id IN (10)
AND a.date_act BETWEEN '2015-08-01' AND DATEADD(day, 1, '2015-09-30')
GROUP BY inc.inc_id,a.date_act,inc.dept_id, inc.usr_id
Result Expected (Sample):
+-----------+--------+------+-----------+--------+---------+-------------+-------------+
| inc_count | inc_id | Year | Month | usr_id | dept_id | Travel_Time | Remote_Time |
+-----------+--------+------+-----------+--------+---------+-------------+-------------+
| 1 | 100 | 2015 | August | 1 | 10 | 500 | 0 |
| 1 | 100 | 2015 | September | 1 | 10 | 250 | 0 |
| 1 | 102 | 2015 | August | 1 | 10 | 150 | 120 |
+-----------+--------+------+-----------+--------+---------+-------------+-------------+
logic :
=> First check the inc_id in incident table reference to the usr_id
=> Retrieve the data from actions table related to usr_id in incident table