我们有一个订单簿和发票系统,我的任务是尝试从这些表中输出每月滚动总数。
但我不知道从哪里开始。我认为还有一些我甚至都不知道的SQL语法。我熟悉INNER / LEFT / JOINS和GROUP BY等,但按日期分组令人困惑,因为我不知道如何将数据限制为仅在当前分组的当前日期。我认为这将涉及将表格加入自己或可能是一个子选择。除了绝对必要之外,我一直认为最好避免使用子选择。
基本上系统有3个表
订单:order_id,currency,order_stamp
orders_lines:order_line_id,invoice_id,order_id,价格
发票:invoice_id,invoice_stamp
order_stamp和invoice_stamp是以整数存储的UTC unix时间戳,而不是MySQL时间戳。
我正在尝试按年/月显示当前未开单的订单总额(价格总和)。在该时间点。
当前订单是order_stamp在该月1日小于或等于00:00的订单
未开单的订单是invoice_stamp为null或invoice_stamp在该月的第1天大于00:00的订单。
在那个时间点,可能还没有相关的发票,invoice_id可能为空。
任何人都有任何关于我应该加入什么以及我需要分组的建议?
干杯,B
答案 0 :(得分:0)
SELECT yr, mon, COALESCE(SUM(price), 0)
FROM (
SELECT 2010 AS yr
UNION ALL
SELECT 2009
UNION ALL
…
) as years
CROSS JOIN
(
SELECT 1 AS mon
UNION ALL
SELECT 2
…
UNION ALL
SELECT 12
) as months
LEFT JOIN
orders o
ON o.order_stamp <= UNIX_TIMESTAMP(CAST(CONCAT(year, mon, '01') AS DATE))
LEFT JOIN
order_lines ol
ON ol.order_id = o.order_id
AND NOT EXISTS
(
SELECT NULL
FROM invoice i
WHERE i.invoice_id = ol.invoice_id
AND i.invoice_stamp > UNIX_TIMESTAMP(CAST(CONCAT(year, mon, '01') AS DATE))
)
GROUP BY
yr, mon
答案 1 :(得分:0)
架构中的日期让我感到困惑......订单标记是订单的UTC,对吧?而invoice_stamp是客户开票时的UTC吗?
我不确定你的“滚动月总数”是什么意思,所以我会假设这是一个月内所有发票的集合?并列出给定月份的所有订单?
未开单的客户是那些没有发票的客户......
如果是这样的话,那就像:
SELECT YEAR(FROM_UNIXTIME(order_stamp)),
MONTH(FROM_UNIXTIME(order_stamp)),
SUM(price)
FROM orders
LEFT JOIN order_lines USING (order_id)
LEFT JOIN invoices USING (invoice_id)
WHERE invoices.invoice_id IS NULL
GROUP BY YEAR(FROM_UNIXTIME(order_stamp)),
MONTH(FROM_UNIXTIME(order_stamp))
......应该让你到那儿。
如果您正在寻找超过30天的东西的收集成本,您需要以下内容:
SELECT YEAR(FROM_UNIXTIME(invoice_date)),
MONTH(FROM_UNIXTIME(invoice_date)),
SUM(OverThirtyDayPrice),
AVG(CollectionDays)
FROM
(
SELECT invoice_date,
IF(
DATEDIFF(
FROM_UNIXTIME(IFNULL(invoice_stamp, UNIX_TIMESTAMP()),
order_stamp) > 30,
price,
0
) AS OverThirtyDayPrice,
DATEDIFF(FROM_UNIXTIME(IFNULL(invoice_stamp, UNIX_TIMESTAMP()),
order_stamp)) AS CollectionDays
FROM orders
LEFT JOIN order_lines USING (order_id)
LEFT JOIN invoices USING (invoice_id)
)
GROUP BY YEAR(FROM_UNIXTIME(invoice_date)),
MONTH(FROM_UNIXTIME(invoice_date))
我们可以稍微破解最后一个,以使其适用于一个月内订购的产品,但在另一个产品中收费:
SELECT YEAR(invoice_datetime),
MONTH(invoice_datetime),
SUM(OutOfMonthPrice)
FROM
(
SELECT FROM_UNIXTIME(IFNULL(invoice_stamp, UNIX_TIMESTAMP())) AS invoice_datetime,
IF(MONTH(
FROM_UNIXTIME(IFNULL(invoice_stamp, UNIX_TIMESTAMP()))
)
<>
MONTH(FROM_UNIXTIME(order_stamp)),
price,
0
) AS OutOfMonthPrice,
FROM orders
LEFT JOIN order_lines USING (order_id)
LEFT JOIN invoices USING (invoice_id)
)
GROUP BY MONTH(invoice_datetime), YEAR(invoice_datetime)
如果您想获得“时间点”查询,您可能会发现RDBMS不是您需要的东西(您需要迭代一系列查询,每个查询都针对特定的月/年)和/或您的基本设计不支持您尝试生成的报告。
理想情况下,您想要的是存档和报告的月度报告。