Евгений Колесников 1 年之前
父节点
当前提交
8111c39a53
共有 1 个文件被更改,包括 47 次插入0 次删除
  1. 47 0
      articles/cs_mysql_connection3.md

+ 47 - 0
articles/cs_mysql_connection3.md

@@ -180,6 +180,53 @@
     dotnet add package Dapper
     ```
 
+## Выборка из связанных таблиц
+
+По заданию нам необходимо выводить список и стоимость материалов. Данные эти достаются через таблицу связей **ProductMaterial**, т.е. в каждом продукте может использоваться несколько материалов.
+
+Для формирования этих полей можно использовать два варианта:
+
+1. Сразу запрашивать все данные. В этом случае получается достаточно сложный запрос (и с точки логики и с точки зрения времени выполнения).
+
+1. Запрашивать данные по мере отображения. В этом случае запросы получаются простыми, а все данные могут никогда и не понадобиться (**WPF** запрашивает данные только при отображении)
+
+Рассмотрим первый вариант:
+
+```sql
+SELECT 
+	p.ID ,
+	p.Title ,
+	p.ProductTypeID ,
+	p.ArticleNumber,
+	p.Image ,
+	pt.TitleType AS ProductTypeTitle,
+	qq.MaterialCost, qq.MaterialString 
+FROM 
+	Product p
+LEFT JOIN 
+    ProductType pt on p.ProductTypeID = pt.ID
+LEFT JOIN 
+	(
+        select 
+		    pm.ProductID, 
+            SUM(pm.`Count` * m.Cost) AS MaterialCost,
+            GROUP_CONCAT(m.Title, ',') AS MaterialString
+	    FROM 
+		    ProductMaterial pm,
+		    Material m 
+	    WHERE
+		    pm.MaterialID=m.ID
+	    GROUP BY 
+            pm.ProductID	
+    ) AS qq ON qq.ProductID=p.ID ;
+```
+
+**Во-первых**, у нас появляется параметр **LEFT JOIN ... ON ...**. В принципе это аналог **FROM ... WHERE ...**, отличие в том, что если для указанного продукта в таблице связей не будет материалов, то обычный **FROM** исключит этот продукт из выборки (умножение на `0`). **LEFT JOIN** позволяет **добавить** к основной таблице поля из свзянных таблиц, даже если данных для них нет (поля будут заполнены **NULL**). Таблицу **ProductType** тоже приходится цеплять через **JOIN**, т.к. в синтаксисе **MySQL** допускается только одна таблица во **FROM**, если в запросе есть **JOIN**-ы.
+
+**Во-вторых**, нам приходится рисовать вложенный запрос для вычисления суммы и строки материалов с группировкой по продуктам.
+
+Такой запрос в принципе можно оформить как **VIEW**
+
 Реализацию графической части я не делаю - используйте лекции по **ОАП**
 
 ---