这是Microsoft SQL,而不是Mysql。
我有一张表格,其中包含发送给客户的货件的发票数据。
例如,数据可能如下所示:
INVOICE DATE | QUANTITY | PRODUCT | VENDOR ID
2014-07-31 | 25 | Oranges | 12
2014-08-12 | 14 | Apples | 12
2014-09-01 | 135 | Oranges | 12
2015-07-04 | 18 | Oranges | 12
2015-07-12 | 35 | Apples | 12
如您所见,数据中存在空白,我们未在特定月份向该客户发送订单。
我试图得到一个月的列表,所以我可以在图表上显示它(chartJS是具体的)所以我需要空值,这些记录不存在所以我们有一个12个值的字符串,即使它们&# 39;在给定年份全部为零。
现在,我们在PHP循环中使用不同的查询(非常糟糕)来实现这一点,就像这样
while($i = 1; $i < 13; $i++) {
$query = "Select sum(quantity), month, year
From Table
where month = $i
and year = $year
and vendorID = 12"
}
这导致产生如下的数据集,我们每个月得到一个数据集,如果没有结果,我们得到零。
month | year | quantity
... | ... | ...
6 | 2014 | 0
7 | 2014 | 25
8 | 2014 | 14
9 | 2014 | 135
10 | 2014 | 0
.... | .... | ....
不幸的是,这需要我们想要显示的每年12个查询。我希望能够在一个查询中获得相同的数据。
不幸的是,更新的查询仅在发票日期存在时返回结果。有没有办法使用SQL而不是PHP来循环所有可能的月份,以便使用聚合查询来获取此信息?
我已经得到以下查询,但它只给出了发票日期存在的结果:
Select sum(quantity), month, year
from table where VendorID = 12
and InvoiceDate between '1/1/2014' and '12/31/2014'
GROUP BY year, month
结果:
Quantity | Month | Year
25 | 7 | 2014
14 | 8 | 2014
135 | 9 | 2014
53 | 7 | 2015
正如您所看到的,这仅提供带有值的结果,而不是带有零的所有月份。
感谢贡献者,我有一个有效的解决方案查询,是两种建议的组合
DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
Set @StartDate = '7/1/2014'
SET @EndDate = '12/1/2015'
;with cal as (
SELECT @StartDate AS [Date]
UNION ALL
SELECT DATEADD(month, 1, [Date])
FROM cal
WHERE [Date] < @EndDate
)
select coalesce(a.qty, 0) as qty,
DATEPART(month, cal.[Date]) AS [month],
DATEPART(year, cal.[Date]) AS [year] from
(
SELECT sum(qty) as qty,
[month],
[year]
from ship_table
WHERE vendorID = 12
group by [year], [month]
) A
right join cal ON DATEPART(month, cal.[Date])=A.[month]
AND DATEPART(year, cal.[Date])=A.[year]
答案 0 :(得分:2)
请尝试以下查询。我已使用数据透视表填写月份数字。
我假设年份保持不变,即2014
(证明使用ISNULL(year,2014)
)或者可以通过某种方式从YEAR(@startmonth)
我还为demo创建了一个sql小提琴: http://sqlfiddle.com/#!6/9dc17/2
select ISNULL(A.quantity,0) as quantity,cal.Num as Month,ISNULL(year,2014) from
(Select sum(quantity) as quantity, month(InvoiceDate) as month, year(InvoiceDate) as year
from [table]
where VendorID = 12
and InvoiceDate between '1/1/2014' and '12/31/2014'
GROUP BY year(InvoiceDate), month(InvoiceDate)) A
right join
(select mon,num from
(
select 1 as [Jan],2 as [feb],3 as [mar],4 as [apr],5 as [may],6 as [jun],7 as [jul],8 as [aug],9 as [sep],10 as [oct],11 as [nov],12 as [dec]) s
UNPIVOT
(
Num for Mon in ([jan],[feb],[mar],[apr],[may],[jun],[jul],[aug],[sep],[oct],[nov],[dec])
)up) cal
on A.month=Cal.Num
答案 1 :(得分:2)
以下是我开车的答案。
根据您问题中的查询代码,我假设您的表中包含名为&#34; Month&#34;和&#34;年&#34;,它们的使用方法与查询相同。
假设您将StartDate和EndDate参数传递给您的查询,那么您可以获得任何日期范围:
WITH cte AS (
SELECT @StartDate AS [Date]
UNION ALL
SELECT DATEADD(month, 1, [Date])
FROM cte
WHERE [Date] <= @EndDate
)
Select
sum(quantity),
DATEPART(month, cte.[Date]) AS [month],
DATEPART(year, cte.[Date]) AS [year]
from table t
RIGHT OUTER JOIN cte
ON DATEPART(month, cte.[Date])=t.month
AND DATEPART(year, cte.[Date])=t.year
where VendorID = 12
GROUP BY DATEPART(month, cte.[Date]) AS [month],
DATEPART(year, cte.[Date]) AS [year]