SQL-запрос с функцией

У меня есть таблица данных, которую я использую оператор подсчета, чтобы получить количество записей для примера даты представления

AuditId Date    Crew    Shift   Cast    ObservedBy  2ndObserver AuditType   Product
16  2017-06-27  3   Day         B1974, B1975    Glen Mason  NULL    Identification  Billet    
20  2017-06-29  1   Day         9879    Corey Lundy NULL    Identification  Billet
21  2017-06-29  4   Day         T9627, T9625    Joshua Dwyer    NULL    ShippingPad Tee       
22  2017-06-29  4   Day         NULL    Joshua Dwyer    NULL    Identification  Billet    
23  2017-06-29  4   Day         S9874   Joshua Dwyer    NULL    ShippingPad Slab      
24  2017-06-29  4   Day         Bay 40  Joshua Dwyer    NULL    Identification  Billet    

В основном я использую следующий код, чтобы получить свои результаты

SELECT YEAR([Date]) as YEAR, CAST([Date] as nvarchar(25)) AS [Date], COUNT(*) as "Audit Count"
        FROM    AuditResults
        where AuditType = 'Identification' AND Product = 'Billet' 
        group by Date

это возвращает пример

YEAR  Date  Audit Count
2017    2017-06-27  1
2017    2017-06-29  3

Теперь я хочу получить все даты, даже если они не указаны, поэтому я хочу, чтобы возврат был

YEAR  Date  Audit Count
2017  2017-06-27    1
2017  2017-06-28    0
2017  2017-06-29    3

У меня есть следующая функция, которую я пытаюсь использовать:

ALTER FUNCTION [dbo].[fnGetDatesInRange]
(   
    @FromDate datetime,
    @ToDate datetime
)
RETURNS @DateList TABLE (Dt date) 
AS
BEGIN
    DECLARE @TotalDays int, @DaysCount int


      SET @TotalDays =  DATEDIFF(dd,@FromDate,@ToDate)
      SET @DaysCount = 0


        WHILE @TotalDays >= @DaysCount
        BEGIN
                INSERT INTO @DateList
                SELECT (@ToDate - @DaysCount) AS DAT


                SET @DaysCount = @DaysCount + 1
        END
        RETURN
END

Как мне использовать мой оператор выбора с этой функцией? или есть лучший способ? ура

2 ответа

Решение

Попробуй это;

ALTER FUNCTION [dbo].[fnGetDatesInRange]
(   
    @FromDate datetime,
    @ToDate datetime
)
RETURNS @YourData TABLE ([Year] int, DateText nvarchar(25),[Audit Count] int) 
AS
begin
insert into @YourData
SELECT 
    YEAR(allDates.[Date]) as YEAR, 
    CAST(allDates.[Date] as nvarchar(25)) AS [Date], 
    COUNT(r.Product) as "Audit Count"
from
    (
    SELECT 
        [date]=convert(datetime, CONVERT(float,d.Seq))
    FROM 
        (
        select top 100000 row_number() over(partition by 1 order by A.name) as Seq 
        from syscolumns A, syscolumns B  
        )d 
    )allDates
left join
    AuditResults r on r.[Date]=allDates.[date] and  r.AuditType = 'Identification' AND r.Product = 'Billet' 
where
    allDates.[Date]>=@FromDate and allDates.[Date]<=@ToDate
group by    
    allDates.[Date]

return
end

Ключом является раздел "allDates";

SELECT 
    [date]=convert(datetime, CONVERT(float,d.Seq))
FROM 
    (
    select top 100000 row_number() over(partition by 1 order by A.name) as Seq 
    from syscolumns A, syscolumns B  
    )d

Это вернет все даты между 1900 и 2173 (в этом примере). Ограничьте это по мере необходимости, но хороший вариант. Тонна разных способов подойти к этому ясно

Вы должны создать другую таблицу calendar as (Mysql)- идея одинакова на всех RDBMS-

CREATE TABLE `calendar` (
    `dt` DATE NOT NULL,
    UNIQUE INDEX `calendar_dt_unique` (`dt`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

и заполните данные даты.

больше деталей

Другие вопросы по тегам