天天看点

mysql关系表的使用_如何在MySQL中以一对多的关系使用表A连接两个表?

问题是您的查询正在生成笛卡尔积(类似)结果集。

基本上,对于来自'secondaries'的每个匹配行,'main'中的一行会重复多次。

要获得所需的结果,请一次加入sales表,并匹配StoreID和ParentID。

要获取Individual Sales,仅包含StoreID匹配的SUM行,如下所示:

SELECT Store.ID AS `Store ID`

, SUM(IF(main.StoreID = Store.ID,

IF(YEAR(main.SalesDate) = 2012 AND QUARTER(main.SalesDate) = 1,main.SalesAmount,0)

,0)) AS `Individual Sales`

, SUM(

IF(YEAR(main.SalesDate) = 2012 AND QUARTER(main.SalesDate) = 1,main.SalesAmount,0)

) AS `Consolidated Sales`

FROM Store

LEFT JOIN Sales AS `main` ON main.StoreID = Store.ID OR main.StoreID = Store.ParentID

GROUP BY Store.ID

更新 B>

我的错。 (DOH!)ParentID位于Store表中,而不是Sales表。

上面的查询不返回指定的结果。 (正在努力。)

我觉得你已经有了解决方案......

使用ParentID列代替Store表中的ID列。

在ParentID列为NULL的情况下,我们使用ID列中的值。

SELECT IFNULL(Store.ParentID,Store.ID) AS `Store ID`

, SUM(IF(main.StoreID = Store.ID,

IF(YEAR(main.SalesDate) = 2012 AND QUARTER(main.SalesDate) = 1,main.SalesAmount,0)

,0)) AS `Individual Sales`

, SUM(

IF(YEAR(main.SalesDate) = 2012 AND QUARTER(main.SalesDate) = 1,main.SalesAmount,0)

) AS `Consolidated Sales`

FROM Store s

LEFT JOIN Sales AS `main` ON main.StoreID = Store.ID OR main.StoreID = Store.ParentID

GROUP BY IFNULL(Store.ParentID,Store.ID)击>

此查询返回指定的结果集:

SELECT t.StoreID AS `Store ID`

, SUM(IF(t.source='p',

IF(YEAR(t.SalesDate) = 2012 AND QUARTER(t.SalesDate) = 1,t.SalesAmount,0)

,0)) AS `Individual Sales`

, SUM(

IF(YEAR(t.SalesDate) = 2012 AND QUARTER(t.SalesDate) = 1,t.SalesAmount,0)

) AS `Consolodiated Sales`

FROM (

SELECT 'p' AS source

, a.StoreID

, a.SalesDate

, a.SalesAmount

FROM Sales a

UNION ALL

SELECT 's' AS source

, s.ParentID

, b.SalesDate

, b.SalesAmount

FROM Sales b

JOIN Store s ON s.ID = b.StoreID

WHERE s.ParentID IS NOT NULL

) t

GROUP BY t.StoreID

ORDER BY t.StoreID这不是最有效的,内联视图(或“派生表”)是Sales表大小的顺序。将日期中的谓词下推到内联视图中,或者在派生表中按月或按季度汇总会更有效。

我更有可能将“季度”作为结果集的一部分返回,以允许我拉出超过四分之一。

SELECT t.StoreID AS `Store ID`

, t.SalesQuarter

, SUM(IF(t.source='p',t.SalesAmount,0)) AS `Individual Sales`

, SUM(t.SalesAmount) AS `Consolodiated Sales`

FROM (

SELECT 'p' AS source

, a.StoreID

, ADDDATE(MAKEDATE(YEAR(a.SalesDate),1), INTERVAL FLOOR(MONTH(a.SalesDate)/4) QUARTER) AS SalesQuarter

, SUM(a.SalesAmount) AS SalesAmount

FROM Sales a

-- WHERE a.SalesDate >= '2012-01-01'

-- AND a.SalesDate < '2012-04-01'

GROUP BY a.StoreID, SalesQuarter

UNION ALL

SELECT 's' AS source

, s.ParentID

, ADDDATE(MAKEDATE(YEAR(b.SalesDate),1), INTERVAL FLOOR(MONTH(b.SalesDate)/4) QUARTER) AS SalesQuarter

, SUM(b.SalesAmount) AS SalesAmount

FROM Sales b

JOIN Store s ON s.ID = b.StoreID

WHERE s.ParentID IS NOT NULL

-- AND a.SalesDate >= '2012-01-01'

-- AND a.SalesDate < '2012-04-01'

GROUP BY s.ParentID, SalesQuarter

) t

GROUP BY t.StoreID, t.SalesQuarter

ORDER BY t.StoreID, t.SalesQuarter