Let's say I have this kind of MySQL database structure :
Menu :
id name
3 Tartiflette
4 Lasagne
Ingredient :
id name price
15 Carrot 2.00
39 Garlic 3.00
40 Reblochon 5.00
55 Onion 1.00
Menu_ingredient :
id ingredient_id menu_id quantity
4 15 4 2
5 55 4 1
6 39 4 1
7 40 3 2
8 55 3 3
Resa_menu :
id resa_id menu_id people
1 1 4 3
2 1 3 2
Resa :
id
1
How could I get all the ingredients from one reservation, using one query parameter with the items/ endpoint ?
I tried the query using items/resa_menu?fields=*.* (and some other combinations, but out of luck).
I also set up an SQL View (virtual table) getting all info needed with a query, but this kind of SQL doesn't seem to be fetched by Directus.
SELECT
ingredient.name as ing_name,
(resa_menu.people * ingredient.price) as price,
(resa_menu.people * menu_ingredient.quantity) as quantity
FROM resa_menu
INNER JOIN menu ON menu.id = resa_menu.menu_id
INNER JOIN resa ON resa.id = resa_menu.resa_id
INNER JOIN menu_ingredient ON menu_ingredient.menu_id = menu.id
INNER JOIN ingredient ON ingredient.id = menu_ingredient.ingredient_id
GROUP BY ingredient.id;
Expected output :
ing_name price quantity
Carrot 6.00 6
Garlic 9.00 3
Reblochon 10.00 4
Onion 3.00 3
The specific goal here is to get a summary of all ingredients needed for the reservation (combining all menus, multiplying quantity by number of people). But my question is more generic on : how can you do multiple JOINs like in this query with Directus API ?
Many thanks for the help!
I think what you mean is you're requesting the endpoint /items/Resa_menu and doing *.* is returning Menu_ingredient related data, however you would like a list of ingredients returned too? for this, would you not just change your fields query to *.*.* to get three levels of relations?
Or is it that the ?fields=*.* simply isn't working at all?
use left join and you does not need group by
select i.name,(i.price* coalesce(rm.people,1)) as price,
(mi.quantity*coalesce(rm.people,1)) as quantity
from Ingredient i left join
Menu_ingredient mi on i.id =mi.ingredient_id
left join Resa_menu rm on mi.menu_id =rm.menu_id
Related
I'm facing a problem with Postgres. Here is the example:
i got 3 tables: users, items and boxes
boxes table:
user_id | item_id
1 | 3
1 | 4
1 | 6
1 | 7
2 | 5
2 | 10
2 | 11
3 | 5
3 | 6
3 | 7
Given this boxes table, i would like to retrieve items among users who share minimum 2. So the SQL query result expected should be
item_id: 6, 7
because user 1 and user 3 share items 6 and 7.
But user 2 and 3 share only one item: the item 5 so item 5 is not in result.
I'm trying so many ways without success. I wonder if someone can help me.
Try this. It returns 6 and 7 (and 5,6,7 if you add a record "1,5"), but I haven't tested it extensively.
-- The Outer query gets all the item_ids matching the user_ids returned from the subquery
SELECT DISTINCT c.item_id FROM boxes c -- need DISTINCT because we get 1,3 and 3,1...
INNER JOIN boxes d ON c.item_id = d.item_id
INNER JOIN
--- the subquery gets all the combinations of user ids which have more than one shared item_id
(SELECT a.user_id as first_user,b.user_id as second_user FROM
boxes a
INNER JOIN boxes b ON a.item_id = b.item_id AND a.user_id <> b.user_id -- don't count items where the user_id is the same! Could just make the having clause be > 2 but this way is clearer
GROUP BY a.user_id,b.user_id
HAVING count(*) > 1) s
ON s.first_user = c.user_id AND s.second_user = d.user_id
I have three tables: the first has a list of category IDs, the second has dataset information, and the third has import information.
What I have
select dataset.pc_id , count(*)
from import
join dataset on CAST (dataset.internal_id as varchar(20)) = import.product_id
group by dataset.pc_id, order by pc_id asc
This will output:
3 4
4 5
6 200
7 192
8 1000
Where product_category comes into play is this: I want the output to look like:
1 0
2 0
3 4
4 5
6 200
...
16 0
The 16 are the number of different product categories from the product_category table that I currently cannot figure out how to fit into that statement.
What is the way to get all the id's from product category into this list with the information joined occupying the result?
Figured it out, needed to get rid of selecting dataset.pc_id and just go with product_category.id and then right join product_category.
I've already searched for my problem, but most of the examples (if not all), have to deal with only one or two tables with a one-to-many relationship between them.
So, here goes my scenario:
My first table is:
OrderID Quantity Price
----------------------------------
18 1000.00 160.00
19 1000.00 40.00
22 1000.00 40.00
23 100.00 500.00
24 10.00 50.00
My second table is:
ExtrasID Name
-------------------
1 Value 1
2 Value 2
3 Value 3
4 Value 4
5 Value 5
I have a many-to-many relationship established between the tables above, so there is a third (joint) table which is as follows:
OrderExtrassID OrderExtras_OrderID OrderExtras_ExtrasID
----------------------------------------------------------------
20 19 2
22 22 3
23 23 2
24 23 5
Now, all I want to achieve is to get a result such as the following:
OrderID Extras
----------------------------
18 NULL
19 Value 2
22 Value 3
23 Value 2, Value 5
24 NULL
There are many examples using XML PATH, PIVOT, CTE etc., but none of these seems to help me with my scenario, or at least I've not managed to study them in depth, in order to get my work done...
Thanks in advance,
I would suggest using For XML to return multiple rows into a single row and then using STUFF to removing the extra comma. Something like this:
SELECT O.OrderId
,STUFF(
(
SELECT ',' + E.Name AS [text()]
FROM OrderExtras OE
Inner Join Extras E
ON E.ExtrasId = OE.OrderExtras_ExtrasID
WHERE O.OrderId = OE.OrderExtras_OrderID
ORDER BY E.Name
FOR XML PATH('')
), 1, 1, '') AS ColList
FROM Orders O
And here is the SQL Fiddle.
Good luck.
Following is my table schema.
Channel listing table:
CHAN_NUMBER CHAN_NAME CHAN_TYPE
----------- -----------------------------------
1 MTV Music
2 ESPN Sports
3 TNT Movies
4 Fox Movies
5 Fox Sports
customer survey table:
SURV_ID SURV_DATE SURV_FAV_CHAN CUST_NUMBER
---------- --------- ------------- -----------
1 25-NOV-12 1 2
2 24-NOV-12 2 1
3 24-NOV-12 3 3
4 24-NOV-12 4 4
5 24-NOV-12 5 5
6 24-NOV-12 1 6
7 24-NOV-12 2 7
8 24-NOV-12 3 8
9 24-NOV-12 4 9
10 24-NOV-12 5 10
11 24-NOV-12 1 11
I have these two tables that I need to generate a report that lists every channel and a count of how many customers have selected that channel as their favorite.
On oracle database I got up to the point where I am generating a count of each time a channel was selected as a favorite from the SURVEY table. But I can't figure out how to join them to create a list of channels displaying the channel number, the name and the count of customers who chose it as their favorite.
-- my channel table query
SELECT CHAN_NUMBER, CHAN_NAME FROM CHANNEL;
-- here is how I'm generating the couNt
SELECT COUNT(SURV_FAV_CHAN) FROM SURVEY
GROUP BY SURV_FAV_CHAN HAVING COUNT(SURV_FAV_CHAN) > 1;
ANY HELP WOULD BE AWESOME.
Please check this reference * SQLFIDDLE
You said you want list every channel, and count of how many customers have selected that channel as their favourite.
Let's go from nested to outside. Nested query you count number of customers from Survery table grouping by favourite channel. Every channel means, you need to do a LEFT JOIN on Channels table to get all the records.
Query:
(select c.*, s.ct from
channel c
left join
(select count(cust_number) as ct
, surv_fav_chan from survey
group by surv_fav_chan) as s
on c.chan_number = s.surv_fav_chan
;
Results:
CHAN_NUMBER CHAN_NAME CHAN_TYPE CT
1 MTV Music 3
2 ESPN Sports 2
3 TNT Movies 2
4 Fox Movies 2
5 Fox Sports 2
You seem to treat FOX as two channels offering two different types of programmes. So I have left it as it is. If you want to even count customers by channel type then please clarify.
PS: You may ignore the other old table schema in that SQLFIDDLE table sample. NOTE that it is in MYSQL, however this is an ANSI query - so you may apply it to ORACLE as well.
You can try something like this:
SELECT MAX(CH.CHAN_NUMBER), MAX(CH.CHAN_NAME), COUNT(SRV.SURV_FAV_CHAN) FROM SURVEY SRV
LEFT JOIN CHANNEL CH ON CH.CHAN_NUMBER = SRV.SURV_FAV_CHAN
GROUP BY SRV.SURV_FAV_CHAN HAVING COUNT(SRV.SURV_FAV_CHAN) > 1;
And you may want to use SUM(SRV.SURV_FAV_CHAN) if you really need the total amount of customers if I understand you question correctly
Assuming that SURV_FAV_CHAN and CHAN_NUMBER is the relation, use that for your JOIN, so try this:
SELECT CHAN_NUMBER
, CHAN_NAME
, COUNT(DISTINCT SURVEY.CUST_NUMBER) AS FAV_CHANNEL_CNT
FROM CHANNEL
LEFT JOIN SURVEY
ON SURVEY.SURV_FAV_CHAN = CHANNEL.CHAN_NUMBER
GROUP BY CHAN_NUMBER, CHAN_NAME
I have a table that reuses a foreign key and I'd like to join a different value for each case. The first table describes a drug dosing activity. It has ID's that point to drugs, routes, vehicles, etc... The confusing thing is that it reuses the Unit ID which is a foreign key in a single description table.
GROUPS (Simplified)
GROUP_NO DRUG DRUG_AMOUNT DRUG_UNIT CHECK_UNIT
1 568 5 7 5
2 689 1 7 5
2 568 5 7 5
3 19 0.5 10
4 984 10 10 5
UNITS (Simplified)
UNIT_ID UNIT_DESCR
5 kg
7 mg
10 mL
I'd like to generate a query that returns a row for each drug dose for all groups. I can do everything but the units. I'd like to use a CASE statement to display the dosing units. The select statement would look something like this:
'DOSE UNITS' =
CASE
WHEN CHECK_UNIT IS NULL THEN DRUG_UNIT_DESCR
ELSE CONCAT(DRUG_UNIT_DESCR+'/'+CHECK_UNIT_DESCR)
END
I'm trying to get the results to look like such for this example:
RESULT
GROUP_NO DRUG DRUG_AMOUNT 'DOSE UNITS'
1 HelpsAlot 5 mg/kg
2 HelpsMore 1 mg/kg
2 HelpsAlot 5 mg/kg
3 DoesNothing 0.5 mL
4 WhoKnows 10 mL/kg
Thanks for any help.
You need two joins, one for each key:
select g.*,
'DOSE UNITS' = (CASE WHEN CHECK_UNIT IS NULL THEN du.UNIT_DESCR
ELSE CONCAT(du.UNIT_DESCR+'/'+cu.UNIT_DESCR)
END)
from groups g left outer join
units cu
on g.check_unit_id = cu.unit_id left outer join
units du
on g.drug_unit_id = du.unit_id
assuming drug_unit is always populated
select group_no, drug, drug_amount,
'dose units' =
case
when check_unit is null then u1.unit_descr
else concat(u1.unit_descr+'/'+ u2.unit_descr)
end
from groups g inner join units u1
on g.drug_unit = u1.unit_id
left join units u2
on g.check_unit = u2.unit_id