我有一张汽车表,基本上包括所有销售清单。表格如下:
carType, soldDate, price
我想生成一个显示每个月总计的结果,包括没有条目(没有销售额)的月份,按月份和年份分组,但也按carType
分组。我有以下SQL查询,但我似乎无法弄清楚如何包含所有缺少的月份:
SELECT
carType, YEAR(date) AS year, MONTH(date) as month, SUM(amount)
FROM
cars
GROUP BY
YEAR(date), MONTH(date), carType
ORDER by
carType, year, month
我还想运行查询,没有设置开始和结束日期以及指定的开始和日期(如在两个不同的查询中)。任何有关如何做到这一点的帮助将不胜感激。
答案 0 :(得分:0)
一种解决方案是使用包含所有年份和月份的期间的表格。
然后,使用查询结果进行外部联接。
答案 1 :(得分:0)
这是不可能的。根据JeffRichards对这个问题的评论,如果数据不存在,那就不存在了。您可以尝试在另一个临时表(可能非常复杂)中预先填充它以及许多其他可能的选项,但Jeff所说的最佳解决方案实际上是在另一层编写它。这就是我所做的,而且代码非常易于管理。
如果您在Java中执行此操作,则可以使用以下代码创建所需月份和年份的列表:
// You could also .map() it to YearMonth instead of LocalDate's
// The plusMonths(1) is import so that it includes the last month
List<LocalDate> allMonths = Stream.iterate(startDate, date -> date.plusMonths(1))
.limit(ChronoUnit.MONTHS.between(startDate, endDate.plusMonths(1)))
.collect(Collectors.toList());
然后,您将浏览SQL生成列表并添加任何缺失的月份:
allMonths.stream()
.forEach(date ->
{
totalCarList.stream()
.filter(car -> isSameMonthAndYear(car.getTotal().getDate, date))
.findAny()
.orElseGet(() ->
{
totalCarList.add(new Total(date, 0.00))
});
});
最后,您只需按日期对列表进行重新排序:
totalCarList.sort(Comparator.comparing(Total::getDate));
当然有不同的方法,但是它的复杂程度要小得多,然后尝试将其推入SQL层,而SQL层用于处理现有数据,而不是试图将数据推送到不存在的地方。前...