Предположим, у меня есть база данных клиентов, которые покупают материалы, которые «применимы» к случайным объектам. Например, Джон покупает 10 долларов США «Материал X», который применим к машине и к дому.Выпуск нормализации, агрегации и объединения таблиц
Customers
+----+-------+
| ID | Name |
+----+-------+
| 1 | John |
| 2 | Larry |
+----+-------+
Orders
+---------+------------+-------+----------+
| OrderID | CustomerID | Sales | Material |
+---------+------------+-------+----------+
| 1 | 1 | 10 | x |
| 2 | 1 | 15 | x |
| 3 | 1 | 6 | y |
| 4 | 2 | 3 | x |
| 5 | 2 | 25 | y |
+---------+------------+-------+----------+
Моя Materials
таблица первоначально выглядел как этот
+----------+-------------------------+
| Material | Applicability |
+----------+-------------------------+
| x | car, house, plane, bike |
| y | car, bike |
+----------+-------------------------+
Когда мне нужно показать, какие материалы Джон покупает и какие объекты этот материал применим к, мой запрос это.
Select ID, Name, sum(Sales), Material, Applicability
FROM Customers a
INNER JOIN Orders b on a.ID = b.CustomerID
INNER JOIN Materials c on b.Material = c.Material
WHERE Name = 'John'
GROUP BY ID, Name, Material, Applicability
Результат
+----+------+--------------+----------+-------------------------+
| ID | Name | Total Sales | Material | Applicability |
+----+------+--------------+----------+-------------------------+
| 1 | John | 25 | x | car, house, plane, bike |
| 1 | John | 6 | y | car, bike |
+----+------+--------------+----------+-------------------------+
, разделенные запятой значения (я знаю, что это нарушает многие правила) было удобно, потому что при анализе применимости я мог бы просто разделить строку через запятую, а затем я был список объектов применимости.
Теперь это было решено нормализовать Materials
таблицу, так что теперь он выглядит так
+----------+---------------+
| Material | Applicability |
+----------+---------------+
| x | car |
| x | house |
| x | plane |
| x | bike |
| y | car |
| y | bike |
+----------+---------------+
Эта нормализация нарушенного мой существующий запрос, он вызывает sum(sales)
результат быть кратна однако многие объекты материала применимо.
Пример.
+----+------+-------------+----------+---------------+
| ID | Name | Total Sales | Material | Applicability |
+----+------+-------------+----------+---------------+
| 1 | John | 25 | x | car |
| 1 | John | 25 | x | house |
| 1 | John | 25 | x | plane |
| 1 | John | 25 | x | bike |
| 1 | John | 6 | y | car |
| 1 | John | 6 | y | bike |
+----+------+-------------+----------+---------------+
Теперь, похоже, Джон купил 100 долларов материала x, когда он действительно купил 25 долларов США. Мне нужно показать покупателю John предмет материала x, а также применимость x.
Основная проблема заключается в том, когда мне нужно выяснить, что Джон покупает, но также фильтрует по применимости.
Select ID, Name, sum(Sales), Material, Applicability
FROM Customers a
INNER JOIN Orders b on a.ID = b.CustomerID
INNER JOIN Materials c on b.Material = c.Material
WHERE Name = 'John' and (applicability = 'car' or applicability = 'bike')
GROUP BY ID, Name, Material, Applicability
Если какой-либо материал применим как к машине и велосипеде, то совокупная стоимость sum(sales)
будет удвоено.
Как справиться с этим дублированием?
Пожалуйста, отметьте вашу базу данных соответствующим образом. И каковы ваши желаемые результаты, такие же, как оригинал? Если вы хотите использовать что-то вроде 'group_concat' для рекомбинации строк в один столбец ... – sgeddes
Добавлен тег sql-server. Да, результат должен быть таким же, единственное отличие - нормализованная таблица материалов. –
Sql Server не поддерживает 'group_concat'. На SO есть несколько примеров того, как это сделать. Помогает ли это: http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-sql-server – sgeddes