2015-03-14 3 views
0

Я нашел похожие вопросы, на которые были получены ответы, но я не могу заставить их работать. У меня есть следующий SQL запрос, но я хочу, чтобы заполнить недостающие даты с 0 значениямиЗаполнение пустых дат хранимой процедурой в sql

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

Какой РСУБД это? Добавьте тег, чтобы указать, используете ли вы 'mysql',' postgresql', 'sql-server',' oracle' или 'db2' - или что-то еще. –

+1

извините - sql-server – Klelund

ответ

0

Вы можете создать StoredProcedure с 2 входными параметрами и 1 выходных параметров и вы можете проверить, если строка существует, то делать свою работу, и в остальное части вы можете установить выходной параметр, как 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 
+0

Когда в этой таблице нет продаж определенной даты, в таблице нет записи. Ваш код дает мне тот же результат. Мне нужны 0-значения для записей messing в таблице. – Klelund

+0

@ Klelund Решение, которое я предоставил, касается, если ваш столбец 'line.date' имеет нулевое значение, тогда coalesce заменит значение null от' 0' –

+0

Yep - но это не так :( – Klelund

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(). Возможно, Microsoft может добавить вид под названием Numbers, который сделал это для нас.

+0

Msg 319, уровень 15, состояние 1, строка 2 Неверно s yntax рядом с ключевым словом 'with'. Если этот оператор является общим табличным выражением, предложением xmlnamespaces или предложением контекста отслеживания изменений, предыдущий оператор должен быть прерван точкой с запятой. Msg 102, Level 15, State 1, Line 14 Неверный синтаксис около '<'. – Klelund

+0

Мне не просто нужно 1..365. Мне нужны конкретные даты всего года или для заданного диапазона дат – Klelund

+0

Эта версия дает более чем достаточно дат для «дат», а затем ограничивает их в внешнем предложении 'where'. –

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 
+0

Я получаю «Msg 156, Level 15, State 1, Line 32 Неверный синтаксис рядом с ключевым словом« OPTION ».» – Klelund

+0

Извините, я оставил запятую в конце группы по заявлению. Я починил это. – Stephan

Смежные вопросы