简体   繁体   中英

SQL JOIN on 3 tables with multiple one-to-many

So, I'm strugglinbg with an SQL query for quit some time now.
Here is what I'd like to accomplish :

Let's say we have 3 Tables : fruit, farmers & sales

These Tables are structured and filled as followed.

Fruits :

__|_fruit______|_taste_
 1| apple      | sweet
 2| banana     | sweet
 3| grapefruit | sour

Farmers :

__|_farmer___|_field_____
 1| ben      | apple
 2| mary     | banana
 3| mike     | grapefruit
 4| joanna   | apple
 5| clara    | grapefruit

Sales :

__|_fruit______|_amount__
 1| apple      | 50
 2| banana     | 25
 3| apple      | 30
 4| grapefruit | 40
 5| banana     | 45
 6| apple      | 30

I'd now like to be able to look which and how many of these fruit have been sold. A result, I could work with, would look something like this
(WHERE fruits.fruit = "apple") :

fruits.fruit | farmers.farmer | sales.amount
apple        | ben            | 50
apple        | joanna         | 30
apple        | null           | 30

or like this
(WHERE fruits.fruit = "banana") :

fruits.fruit | farmers.farmer | sales.amount
banana       | mary           | 25
banana       | null           | 45

or like this
(WHERE fruits.fruit = "grapefruit") :

fruits.fruit | farmers.farmer | sales.amount
grapefruit   | mike           | 40
grapefruit   | clara          | null

I'd store these results in php and could later determine, which farmer has to be paid what amount of money, because the farmers should be paid appropriate, regarding to the sold amount.

I'd like to do this with only one SQL query and without a cross reference table.
My approach to the problem was the following (which did greatly fail) :

SELECT fruits.fruit, farmers.farmer, sales.amount
FROM fruits
JOIN farmers ON farmers.field = fruits.fruit
JOIN sales ON sales.fruit = fruits.fruit
WHERE fruits.fruit = "apple"

The queries last line has to change, in order to get the previously shown results.

Is it reasonable to do this without a crossreference table?
Is it possible to do it?
Is there a completely different approach which would to be preferred here?

Thanks in advance

EDIT#1 : added a missing entry in sales (6)
EDIT#2 : MySQL - Version is 5.7.17

I think you are looking for group by :

SELECT fr.fruit, fa.farmer, sum(s.amount)
FROM sales JOIN
     fruits fr
     s.fruit = fr.fruit LEFT JOIN
     farmers fa
     ON fa.field = fr.fruit 
GROUP BY fr.fruit, fa.farmer;

This will work for MySql 8.0:

with 
  farmers as (
    SELECT row_number() over ( order by null ) rn, farmer, field from farmers
    WHERE field = 'apple'
  ),    
  sales as (
    SELECT row_number() over ( order by null ) rn, fruit, amount from sales
    WHERE fruit = 'apple'
  )
select s.fruit, f.farmer, s.amount
from sales s left join farmers f
on f.rn = s.rn

See the demo
Results:

| fruit | farmer | amount |
| ----- | ------ | ------ |
| apple | ben    | 50     |
| apple | joanna | 30     |
| apple | null   | 30     |

Edit for MySql 5.5:

select s.fruit, f.farmer, s.amount
from (
  select (@row_number1:=@row_number1 + 1) AS rn, fruit, amount
  from sales, (select @row_number1:=0) t
  where sales.fruit = 'apple'
) s left join (
  select (@row_number2:=@row_number2 + 1) AS rn, farmer
  from farmers, (select @row_number2:=0) t
  where farmers.field = 'apple'
) f
on f.rn = s.rn

See the demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM