获得用户分组的总成本

时间:2015-02-11 13:48:53

标签: mysql sql database join pivot

我已经在这个问题上苦苦挣扎了两天了。我有一个用户表,其中包含一些与订单表有关系的值(用户可以有多个订单)。此表与 order_item 有关系(订单可以有多个orderItems)。 Order_Item与发票有关系(order_item可以有多个发票。

分店和商店与用户有一对一的关系。

以下是所有表格中最重要的值:

user:
-userId (int)

order
-orderId (int)
-userId (int)
-inserted (date)

order_item
-orderItemId (int)
-orderId (int)

invoice
-invoiceId (int)
-orderItemId (int)
-cost (double)

这里的外键不言自明。用户>命令中─> OrderItem->发票。 我需要的是一个查询,其中结果中的每一行代表一个用户,其中两列代表2014年和2015年的总销售额(成本总和)。

所以它必须做的是连续显示每个用户的一些信息来自用户表(公司名称,电子邮件等)和两列,总成本为2014年,其中一列基于订单。插入日期值。

一个例子是:

名称:|电子邮件| 2014成本| 2015年费用

Google | info@google.com | €50.000 | €45.000

现在我已经到目前为止,我已经获得了第一笔款项的结果(显示所有用户,无论成本如何),只有当我第二次加入时(计算2015年的费用)我以前总和成本完全搞砸了。

我在连接中尝试了一些选择查询,但我无法使任何查询起作用。它并不像我在SQL中是一个完整的初学者,但这对我来说太复杂了,无法弄清楚这个确切的时刻。

这是我用来获得2014年结果的查询(一旦我在2015年添加了第二次加入,它就搞砸了):

SELECT t.userId, SUM(i.cost),
t.companyName, t.email,
t.website, t.tel, t.priority,
b.name AS Branch, s.name AS `Shop Name` 
FROM `user` AS t
LEFT JOIN branch AS b ON b.branchId = t.branchId
LEFT JOIN shop AS s ON s.shopId = t.shopId
LEFT JOIN `order` AS o ON (o.userId = t.userId AND YEAR(o.inserted) = 2014) 
LEFT JOIN order_item AS oi ON oi.orderId = o.orderId
LEFT JOIN invoice AS i ON i.orderItemId = oi.orderItemId 
GROUP BY t.userId

我真的希望有人可以帮助我。 (我在Navicat 8中使用mySQL / innoDB)。

1 个答案:

答案 0 :(得分:3)

最终,这是您尝试制作的数据透视表的一种形式。您可以将条件直接放在ON聚合中,而不是加入和测试联接'SUM()子句中的年份条件,如:

-- If the year matches, add the cost value into the sum
-- Otherwise, add zero
SUM(CASE WHEN YEAR(o.inserted) = 2014 THEN i.cost ELSE 0 END) AS `2014 Cost`

这消除了对这些额外连接的需要。应用GROUP BY时,它应包括每个组可能不同的所有列。 MySQL允许您从SELECT中省略GROUP BY中的列,其中大多数其他RDBMS会导致查询编译错误。

SELECT 
  t.userId,
  -- Apply the aggregate SUM() conditionally for each year
  SUM(CASE WHEN YEAR(o.inserted) = 2014 THEN i.cost ELSE 0 END) AS `2014 Cost`
  SUM(CASE WHEN YEAR(o.inserted) = 2015 THEN i.cost ELSE 0 END) AS `2015 Cost`
  t.companyName,
  t.email,
  t.website,
  t.tel,
  t.priority,
  b.name AS Branch,
  s.name AS `Shop Name` 
FROM 
  `user` AS t 
  LEFT JOIN branch AS b ON b.branchId = t.branchId
  LEFT JOIN shop AS s ON s.shopId = t.shopId
  LEFT JOIN `order` AS o ON (o.userId = t.userId) 
  LEFT JOIN order_item AS oi ON oi.orderId = o.orderId
  LEFT JOIN invoice AS i ON i.orderItemId = oi.orderItemId 
GROUP BY 
  t.userId,
  -- Adding remaining SELECT fields
  -- though MySQL will allow these to be omitted
  -- without breaking this particular query
  t.companyName,
  t.email,
  t.website,
  t.tel,
  t.priority,
  Branch,
  `Shop Name`