即使缺少月份,也会按月计算总计
Posted
技术标签:
【中文标题】即使缺少月份,也会按月计算总计【英文标题】:totals by month even for if there is a missing month 【发布时间】:2015-01-27 23:46:46 【问题描述】:只是一个快速的,希望....
我只从一个表中按月获取了一些总计(销售价值)。
我遇到的问题是: 如果一个月没有销售,则结果中当然不会返回该月份。有没有办法我可以在一个查询中做到这一点,所以如果没有销售,即“2015 年 1 月”,结果将返回“0.00 - 2015 年 1 月”
我目前拥有的基本SQL是:
SELECT SUM(p.PaymentAmount) AS Total, MONTHNAME(p.PaymentDate) AS Month, YEAR(p.PaymentDate) AS Year
FROM tPayment p
WHERE p.PaymentType = 2
GROUP BY YEAR(p.PaymentDate), MONTH(p.PaymentDate)
如果不选择 php 中的日期范围然后查询每个月和年,我想不出该怎么做...这看起来很乱...所以我想知道我是否可以在单个查询中执行此操作.
非常感谢任何帮助!
【问题讨论】:
您可以在销售字段中为 1 月添加一行 0。 PHP端填空会不会有问题? 考虑nested queries。 也许一个月表与left join
到支付表?
这看起来是你正在做的,但不是一个简单的查询***.com/questions/27600863/…
【参考方案1】:
您应该为自己创建一个单独的表格,其中包含日期,例如
CREATE TABLE `dates` (
`uid` INT NOT NULL AUTO_INCREMENT,
`datestamp` DATE NOT NULL,
PRIMARY KEY (`uid`))
ENGINE = InnoDB;
然后填写
INSERT INTO dates (datestamp)
SELECT ADDDATE('2015-01-01', INTERVAL SomeNumber DAY)#set start date
FROM (SELECT a.i+b.i*10+c.i*100+d.i*1000 AS SomeNumber
FROM integers a, integers b, integers c, integers d) Sub1
WHERE SomeNumber BETWEEN 0 AND (365 * 3)#3 years
那么你可以加入反对它
SELECT SUM(p.PaymentAmount) AS Total, MONTHNAME(p.PaymentDate) AS Month, YEAR(p.PaymentDate) AS Year
FROM tPayment p
LEFT OUTER JOIN dates d
ON d.datestamp = CAST(p.PaymentDate AS DATE)
WHERE p.PaymentType = 2
GROUP BY YEAR(p.PaymentDate), MONTH(p.PaymentDate)
ORDER BY d.datestamp DESC;
不管我是否在这里粗略地提出了查询,这个概念应该适合你
【讨论】:
【参考方案2】:这不是我完成此任务的首选方法,但为了提供多种替代方法,如果您尝试将其全部保存在 mysql 中并避免创建额外的表,我会提供此方法。
SELECT
SUM(p.PaymentAmount) AS Total,
MONTHNAME(p.PaymentDate) AS Month,
YEAR(p.PaymentDate) AS Year
FROM ( SELECT 1 AS m UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9 UNION ALL
SELECT 10 UNION ALL
SELECT 11 UNION ALL
SELECT 12
) AS months
OUTER JOIN tPayment p
ON MONTH(p.PaymentDate) = months.m
WHERE p.PaymentType = 2
GROUP BY YEAR(p.PaymentDate), MONTH(p.PaymentDate)
我认为在运行查询后在一些快速的 PHP 代码中检查它会更容易。
正如Jon B 所建议的那样,创建一个 months 表并加入该表将大大缩短和清理查询。如果你想把它全部保留在你的 MySQL 查询中,我个人会选择他的方法。
【讨论】:
【参考方案3】:如果您的表中有所有月份的数据——但where
子句过滤掉了一个或多个月份的所有行——你可以尝试条件聚合:
SELECT SUM(CASE WHEN p.PaymentType = 2 THEN p.PaymentAmount ELSE 0 END) AS Total,
MONTHNAME(p.PaymentDate) AS Month, YEAR(p.PaymentDate) AS Year
FROM tPayment p
GROUP BY YEAR(p.PaymentDate), MONTH(p.PaymentDate)
这不能保证有效(取决于数据)。但如果是这样,这是解决这个问题的最简单方法。
【讨论】:
这将适用于当前数据,但这只是因为至少存在一种 PaymentType 形式。但是,如果任何一个月都没有付款(尽管这永远不会发生),这对我来说是行不通的,所以我会依靠机会,这对我来说可能不是一个好习惯....(我不知道为什么否决票,对我来说似乎是一个合理的建议/选择......过去我的一些问题也发生过同样的事情......我们都必须在某个地方学习......) @福特。 . .答案中明确解释了这一点。这只是获得所需内容的一种更简单的方法,这可能取决于所使用的数据。以上是关于即使缺少月份,也会按月计算总计的主要内容,如果未能解决你的问题,请参考以下文章