【问题标题】:SQL query with function带函数的 SQL 查询
【发布时间】:2017-07-11 06:00:26
【问题描述】:

我有一个数据表,我正在使用计数语句来获取提交日期的记录数量 例子

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

我如何在这个函数中使用我的 select 语句?或者,还有更好的方法? 干杯

【问题讨论】:

    标签: sql-server tsql stored-functions


    【解决方案1】:

    试试这个;

    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 之间的所有日期(在本例中)。根据需要限制它,但这是一个不错的选择。有很多不同的方法可以清楚地解决这个问题

    【讨论】:

    • 我希望能够为 fromdate 和 todate 传入一个参数
    • 更新了什么?将存储过程合并到函数中?我现在怎么称呼它?
    • select * from [dbo].[fnGetDatesInRange]('2017-05-24','2017-05-30')
    【解决方案2】:

    您必须创建另一个表 calendar 作为 (Mysql)- 想法在所有 RDBMS 上都是相同的-

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

    并填写日期数据。

    more details

    【讨论】:

    • 只是另一种方法。使用语法作为 RDBMS。
    猜你喜欢
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 2018-10-08
    相关资源
    最近更新 更多