使用sql中的存储过程填充空日期

时间:2015-03-14 16:17:20

标签: sql sql-server stored-procedures

我找到了类似的问题已经得到解答,但我似乎无法让它发挥作用。我有以下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)?

非常感谢任何帮助。

3 个答案:

答案 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