2014-05-15 82 views
2

我正在开发一个基于Web的报表系统,作为一个使用MySQL和PHP的学校项目。这是我的数据库的样子。MySQL - 项目总和问题

+-----------------------------------------------+ 
|    Bill       | 
|-----------------------------------------------| 
| BillID (pk) | BillDate | AccID (fk) | 
|---------------|---------------|---------------| 
| 1   | xxxx-xx-xx | 1   | 
| 2   | xxxx-xx-xx | 2   |  
+---------------+---------------+---------------+ 


+---------------------------------------------------------------+ 
|     BillItem          | 
|---------------------------------------------------------------| 
|BillItemID (pk)| Quantity | BillID (fk) |ProductID (fk) | 
|---------------|---------------|---------------|---------------| 
| 1   |   10 |  1  |  1  | 
| 2   |   10 |  1  |  2  |  
| 3   |   10   2  |  2  | 
+---------------+---------------+---------------+---------------+ 

+-----------------------------------------------+ 
|     Product     | 
|-----------------------------------------------| 
| ProductID(pk) | ProductName |  Price  | 
|---------------|---------------|---------------| 
| 1   | Product1 | XX   | 
| 2   | Product2 | XX   | 
| 3   | Product3 | XX   | 
+---------------+---------------+---------------+ 


+-------------------------------+ 
|   Account   | 
|-------------------------------| 
| AccID(pk) | UserName | 
|---------------|---------------| 
| 1   | AA   | 
| 2   | BB   |  
+---------------+---------------+ 

用户购买产品。对于每个产品系统生成一个账单项目。一张账单可以有很多账单项目。用户可以再次购买相同的物品,不同的物品或两者的组合。我想知道用户在特定时间段内从每种产品购买了多少物品。

预计:

+-----------------------------------------------+ 
| ProductName | UserName | Quantity | 
|---------------|---------------|---------------| 
| Product1 |  AA  |  10  | 
| Product2 |  AA  |  10  |  
| Product3 |  AA  |  0  | 
| Product1 |  BB  |  0  | 
| Product2 |  BB  |  10  |  
| Product3 |  BB  |  0  | 
+---------------+---------------+---------------+ 

我尝试至今:

SELECT Product.ProductName AS ProductName, 
Account.UserName AS UserName, 
SUM(Billitem.Quantity) AS Quantity 
FROM billitem 
INNER JOIN Product ON BillItem.ProductID = Product.ProductID 
INNER JOIN Bill ON Billitem.BillID = Bill.BillID 
INNER JOIN Account ON Bill.AccID = Account.AccID 
WHERE Bill.BillDate >= 'xxxx-xx-xx'AND Bill.BillDate <= 'xxxx-xx-xx' 
GROUP BY UserName, ProductName 

结果:

|-----------------------------------------------| 
| ProductName | UserName | Quantity | 
|---------------|---------------|---------------| 
| Product1 |  AA  | 10   | 
| Product2 |  AA  | 10   |  
| Product2 |  BB  | 10   | 
+---------------+---------------+---------------+ 

有什么办法与MySQL查询实现这一目标?

+1

是什么问题?这个结果是什么意思?它预期或你的结果上述查询?其查询结果为 – underscore

+0

。我其实想要类似 –

+0

这样的东西有什么问题? – underscore

回答

1

你有几个问题正在得到你正在寻找的结果。首先,您的ProductAccount表格之间没有直接关系,但是您希望显示两者的笛卡尔积。您可以使用CROSS JOIN来产生所需的结果。

其次,您需要使用您的BillBillItem表的OUTER JOIN并移动WHERE标准为JOIN

SELECT 
    ProductAccounts.ProductName AS ProductName, 
    ProductAccounts.UserName AS UserName, 
    COALESCE(SUM(Billitem.Quantity),0) AS Quantity 
FROM (
     SELECT P.ProductId, P.ProductName, A.AccId, A.UserName 
     FROM Product P CROSS JOIN Account A 
    ) ProductAccounts 
    LEFT JOIN billitem ON BillItem.ProductID = ProductAccounts.ProductID 
    LEFT JOIN Bill ON Billitem.BillID = Bill.BillID 
     AND Bill.BillDate >= 'xxxx-xx-xx' 
     AND Bill.BillDate <= 'xxxx-xx-xx' 
GROUP BY UserName, ProductName 

这里是一个有用的文章,以帮助了解联接:

+0

要解释一下,当你做一个INNER JOIN时,只有当两个表中有一行(通过连接标准连接时,它们都必须满足)才能得到结果。在你的情况下,你想包括一些不存在的东西,以获得零计数。因此,即使没有账单/账单,您也需要获取所有产品/账户的数据。这就是为什么你需要一个'LEFT OUTER JOIN'来包含账单/ billitem。 – Turophile

+0

布拉沃。这正是我期待的。感谢你能这么快回复。真的很感激它。 –

+0

但是当会有大数据时,建议使用CROSS JOIN?它不会花费太多时间吗? –