Соединить одну строку из таблицы с несколькими строками - PullRequest
0 голосов
/ 14 декабря 2011

Это вопрос, касающийся запросов в MySQL.В качестве примера давайте воспользуемся системой, которая отслеживает продажи автомобилей.Есть таблица с salespersons, таблица с sales и таблица, которая связывает их.В большинстве случаев с каждой продажей связан только один человек.Но иногда несколько человек связаны с продажей.

Table sales
id | carId | date
---+-------+-----------
1  | 2     | 11-01-2011
2  | 8     | 11-02-2011
3  | 5     | 11-05-2011

Table link
personId | saleId
---------+-------
2        | 1 
2        | 2 
1        | 3
2        | 3

Table salesperson
id | name  | age
---+-------+----
1  | Barry | 25
2  | Sara  | 32

Чтобы получить данные, я хочу показать информацию о каждой продаже на веб-странице.Но когда несколько человек связаны с продажей, это становится проблематичным.Я попытался применить приведенный ниже запрос в своем коде, после чего PHP обрабатывает исключение, когда несколько человек связаны с одной продажей, но из-за длины таблицы продаж выполнение запроса ниже занимает слишком много времени:

SELECT count(personId) as amount, carId, date
FROM link 
JOIN salesperson ON link.personId = salesperson.id  
JOIN sales ON sales.id = link.saleId
GROUP BY link.saleId

Есть ли более эффективный запрос, который можно использовать?Кстати, индексация таблицы уже сделана.

Ответы [ 5 ]

1 голос
/ 14 декабря 2011

Тогда это просто:

SELECT STRAIGHT_JOIN
    amount, carId, date
FROM (
    SELECT saleId, count(*) as amount
    FROM link
    GROUP BY saleId
    ORDER BY NULL) as amounts
JOIN sales ON sales.id = amounts.saleId;
0 голосов
/ 14 декабря 2011

Если вас интересует аспект производительности, избегайте использования Joins, особенно в mysql.прочитайте эту статью, демонстрирующую эффективные методы кодирования http://phpadvent.org/2011/a-stitch-in-time-saves-nine-by-paul-jones

Для вашей проблемы в первом запросе выберите идентификатор продаж во втором запросе выберите personID из таблицы ссылок в третьем запросе выберите выберите всех людей из таблицы person

Как уже упоминалось в статье, используйте предложение IN при передаче запроса.в коде это выглядит немного длинно, но гораздо эффективнее, чем использование объединения по таблице с 15k + строками

0 голосов
/ 14 декабря 2011

Ваш запрос выглядит нормально, но ваша группа немного странная ...
Попробуйте стандартный подход группировки по всем неагрегированным столбцам, например:

SELECT carId, date, name, age, count(personId) as amount
FROM link 
JOIN salesperson ON salesperson.id = link.personId
JOIN sales ON sales.id = link.saleId
GROUP BY 1,2,3,4;
0 голосов
/ 14 декабря 2011

Я думаю, что проблема может заключаться в том, что вы используете таблицу ссылок в качестве базовой таблицы, а оптимизация базы данных для запроса не очень хорошая.Попробуйте:

SELECT count(sp.personId) as amount, s.carId as carId, s.date as date, sp.name as name, sp.age as age  
FROM sales as s
JOIN link as l ON s.id = l.saleId
JOIN salesperson as sp ON l.personId = sp.id  
ORDER BY l.saleId
0 голосов
/ 14 декабря 2011

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

Кроме того, какой результат вы пытаетесь получить из своего запроса? Похоже, вы пытаетесь получить все продажи, а затем посчитать, сколько продавцов было вовлечено?

...