Упорядочение строк в родительской таблице по сумме столбцов в дочерней таблице - PullRequest
0 голосов
/ 22 апреля 2020

В моей базе данных есть 3 таблицы

companies{
id,
name,
address
}

stores{
id,
name,
address,
company_id
}

invoices{
id,
total,
date_time,
store_id
}

Как видите, каждый магазин связан с компанией через внешний ключ, а также каждый счет-фактура связан с магазином.

Мой вопрос: как мне написать запрос SQL, который вернет все магазины компании и упорядочит их по обороту?

Если я использую запрос:

SELECT s.*,
sum(i.total) as turnover FROM store s
JOIN invoices i
ON i.store_id = s.id 
WHERE YEAR(i.date_time) = 2019;

I например, я могу увидеть оборот одного магазина за 2019 год, но я изо всех сил пытаюсь найти способ получить список магазинов, упорядоченных по обороту за определенный период.

1 Ответ

1 голос
/ 22 апреля 2020

Вам нужно объединить все 3 таблицы:

SELECT *
FROM 
  companies c
  INNER JOIN stores s on s.company_id = c.id
  INNER JOIN invoices i ON i.store_id = s.id 

Это все ваши необработанные данные в подробном списке. Затем вы говорите, что хотите это только для определенной компании:

SELECT *
FROM 
  companies c
  INNER JOIN stores s on s.company_id = c.id
  INNER JOIN invoices i ON i.store_id = s.id 
WHERE c.name = 'Acme Rubber Co'

Тогда вам нужны только суммы магазинов и счетов:

SELECT s.name, i.total
FROM 
  companies c
  INNER JOIN stores s on s.company_id = c.id
  INNER JOIN invoices i ON i.store_id = s.id 
WHERE c.name = 'Acme Rubber Co'

Затем вы хотите установить строку, где каждая строка это один магазин и сумма всех счетов для этого магазина:

SELECT s.name, SUM(i.total)
FROM 
  companies c
  INNER JOIN stores s on s.company_id = c.id
  INNER JOIN invoices i ON i.store_id = s.id 
WHERE c.name = 'Acme Rubber Co'
GROUP BY s.name

И, наконец, вы хотите, чтобы они были в порядке убывания, наибольшее общее количество сначала:

SELECT s.name as storename, SUM(i.total) as turnover
FROM 
  companies c
  INNER JOIN stores s on s.company_id = c.id
  INNER JOIN invoices i ON i.store_id = s.id 
WHERE c.name = 'Acme Rubber Co'
GROUP BY s.name
ORDER BY turnover DESC

Порядок оценки в sql - ОТ (с объединениями), ГДЕ, ГРУППА BY, SELECT, ORDER BY, поэтому я использую разные имена, например, в порядке, по которому я делаю в группе. Концептуально ваш БД видит только имена вещей, выведенные непосредственно предыдущей операцией. Mysql на самом деле не слишком требователен, но некоторые db - вы не могли бы сказать GROUP BY storename на sql сервере, потому что SELECT, который создает псевдоним хранилища, не был запущен во время выполнения группой

Примечание: я не был уверен в том, что вы искали в ГДЕ - вы начали с того, что сказали «оборачиваемость всех магазинов для определенной компании», и закончили тем, что «пытались получить обороты за период»

Если вам нужен период, используйте, например, WHERE somedatecolumn BETWEEN '2000-01-01' AND '2000-12-31' (Между включительно) или WHERE somedatecolumn >= '2000-01-01' AND somedatecolumn < '2001-01-01' (Хорошая схема, которую следует использовать, если в дате также указано время). Почти никогда не целесообразно вызывать функцию в столбце, с которым вы ведете поиск, ie не делать WHERE YEAR(somedatecolumn) = 2000, потому что это отключает индексирование по столбцу и делает поиск очень медленным

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...