我找到了类似的问题已经得到解答,但我似乎无法让它发挥作用。我有以下SQL查询,但我想用0值填充缺少的日期
SELECT
Lines.Item,
CAST(Lines.Date AS Date) AS SalesDate,
ABS(SUM(Lines.Invoiced)) AS QtySoldOnDate
FROM
Lines
WHERE
Lines.Invoiced < 0
AND Lines.Item = 'a158wa'
AND Lines.Date >= '2014-01-01'
AND Lines.Date <= '2014-12-31'
GROUP BY
Lines.Item, Lines.Date
我找到了以下帖子,但我似乎无法使其工作/弄清楚如何合并这两个查询:What is the most straightforward way to pad empty dates in sql results (on either mysql or perl end)?
非常感谢任何帮助。
答案 0 :(得分:0)
您可以使用2个输入参数和1个输出参数创建storedprocedure
并且你可以检查行是否存在然后完成你的工作,在else部分你可以将输出参数设置为o-values
CREATE PROCEDURE yourprocedure
@startDate Date,
@endDate Date,
@OutputPara as nvarchar(100) output
AS
BEGIN
IF EXISTS( Select Lines.Item FROM Lines [Lines.Date] Where [Lines.Date] >= @startDate AND [Lines.Date] <= @endDate)
BEGIN
SELECT
Lines.Item,
COALESCE(CAST(Lines.Date AS Date),'0') AS SalesDate,
ABS(SUM(Lines.Invoiced)) AS QtySoldOnDate
FROM
Lines
WHERE
Lines.Invoiced < 0
AND Lines.Item = 'a158wa'
AND [Lines.Date] >= @startDate
AND [Lines.Date] <= @endDate
GROUP BY
Lines.Item, [Lines.Date]
Set @OutputPara =' result exists'
END
ELSE
BEGIN
SET @OutputPara='0-results';
END
END
GO
答案 1 :(得分:0)
最简单的方法是获取365个值的列表以形成日期。一种方法是master..spt_values
,类似这样:
with dates as (
select dateadd(day, row_number() over (order by (select null)),
cast('2014-01-01' as date)) as thedate
from master..spt_values
)
SELECT l.Item, d.thedate AS SalesDate,
ABS(SUM(l.Invoiced)) AS QtySoldOnDate
FROM dates d left join
Lines l
ON l.Date = d.thedate and
l.Invoiced < 0 AND
l.Item = 'a158wa'
WHERE d.thedate BETWEEN '2014-01-01' AND Lines.Date <= '2014-12-31'
GROUP BY l.Item, d.theDate;
注意:如果您使用Number
,也可以直接从master..spt_values
阅读type = 'P'
列。我可能会忘记type
部分,因此我只使用了row_number()
。也许微软可以为我们添加一个名为Numbers
的视图。
答案 2 :(得分:0)
我假设你想要什么都不卖的日子,拥有自己的0行作为它的值。由于我没有你的桌子或任何数据,这可能是你做的一些调整。
DECLARE @startDate DATE,
@endDate DATE;
SET @startDate = '2014-01-01';
SET @endDate = '2014-12-31';
--Generates table of each day in range
WITH cte_dates
AS
(
SELECT @startDate AS startDate
UNION ALL
SELECT DATEADD(DAY,1,startDate)
FROM cte_dates
WHERE startDate <= @endDate
)
SELECT cte_dates.startDate,
Lines.Item,
CAST([Lines.Date] AS Date) AS SalesDate,
ISNULL(ABS(SUM(Lines.Invoiced)),0) AS QtySoldOnDate
FROM cte_dates
--Left join makes it where if there is no date in Lines, then cte_dates will be there with nulls for columns in your table Lines
LEFT JOIN Lines
ON cte_dates.startDate = Lines.[Date]
WHERE
Lines.Invoiced < 0
AND Lines.Item = 'a158wa'
AND Lines.Date BETWEEN @startDate AND @endDate
GROUP BY Lines.Item,Lines.[Date],cte_dates.startDate
--It's a recursive CTE. This allows it recursively iterate enough times to generate the list of dates
OPTION (MAXRECURSION 0)
理论结果:
StartDate Item SalesDate QtySOldOnDate
---------------------------------------------------
2014-01-01 Item1 2014-01-01 500
2014-01-02 NULL NULL 0
2014-01-03 Item2 2014-01-03 250