SQL JOIN на 3 таблицы с несколькими один ко многим - PullRequest
0 голосов
/ 25 марта 2019

Итак, я уже давно борюсь с SQL-запросом на выход.
Вот что я хотел бы сделать:

Допустим, у нас есть 3 таблицы: фрукты, фермеры и продажи

Эти таблицы структурированы и заполнены следующим образом.

Фрукты:

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

Фермеры:

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

Продажа:

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

Теперь я хотел бы иметь возможность посмотреть, какие и сколько этих фруктов было продано. Результат, с которым я мог бы работать, выглядел бы примерно так
(ГДЕ fruits.fruit = "яблоко"):

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

или как это
(ГДЕ fruits.fruit = "банан"):

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

или как это
(ГДЕ fruits.fruit = "грейпфрут"):

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

Я бы сохранил эти результаты в php и позже мог бы определить, какому фермеру нужно заплатить, какую сумму, потому что фермерам нужно платить надлежащим образом в отношении проданной суммы.

Я хотел бы сделать это только с одним запросом SQL и без таблицы перекрестных ссылок.
Мой подход к проблеме был следующий (который потерпел неудачу):

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"

Последняя строка запросов должна измениться, чтобы получить ранее показанные результаты.

Разумно ли это делать без таблицы перекрестных ссылок?
Возможно ли это сделать?
Есть ли здесь совершенно другой подход, который предпочтительнее здесь?

Заранее спасибо

РЕДАКТИРОВАТЬ # 1: добавлена ​​отсутствующая запись в продажах (6)
РЕДАКТИРОВАТЬ # 2: MySQL - версия 5.7.17

Ответы [ 2 ]

0 голосов
/ 25 марта 2019

Это будет работать для 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

См. Демоверсию Результаты:

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

Редактировать для 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

См. демо

0 голосов
/ 25 марта 2019

Я думаю, что вы ищете 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...