【问题标题】:SQL to display the all the non transactional hrsSQL 显示所有非事务性小时
【发布时间】:2019-07-20 09:09:11
【问题描述】:

我每小时显示交易数量,效果很好。但是,现在我需要显示发生 0 个事务的 hr 以及存在的 hrs 事务。所以显示小时数,如果该小时内没有事务计数,则显示 0。

不确定我是否能够正确解释我真的很抱歉(如果我不这样做),但下面的 SQL 语句和输出将帮助您理解我想要实现的目标。

我在 SQL Server 上运行的 SQL 查询是

   SELECT CAST([transOcurredOn] AS DATE) as Dategg, 
   DATEPART(HH,transOcurredOn) as 'hour',
   COUNT(*) AS 'Trans count'
   FROM [tpTrans]
   WHERE [transOcurredOn] > '2016-06-18' 
   GROUP BY CAST([transOcurredOn] AS DATE) ,DATEPART(HH,transOcurredOn)
   ORDER BY Dategg,hour

所以我的当前输出看起来像

我的新输出应如下所示,涵盖整个 7 到 23 小时的时钟。我突出显示了更改

我有点挣扎,如果有人指出我正确的方向,不胜感激

块引用

ing,应用程序

【问题讨论】:

  • 创建一个可能的小时数表(24 行),dynamically 或作为一个实际表,并将您现有的查询与它左连接。如果您也有几天根本没有交易,还可以生成一个可能的日期列表,将其交叉连接到可能的时间,然后将结果与您现有的查询一起左连接。
  • 不确定我是否理解正确,但如何加入没有关系的临时表。例如如果我创建一个临时表来填充计数 1 到 24,如何在不循环的情况下在不同的日期连续显示相同的值。?我跑了一整年,我不知道哪个 hr 没有交易。这是一个 15 小时的操作
  • 交叉连接不需要连接条件。
  • 所以我创建了临时表,插入了从 7 到 23 小时的工作时间并添加了交叉连接,它弄乱了事务计数输出。我尝试将 hr 列添加到查询中,并且它已经 3 分钟的查询仍在运行。所以我杀了它。 SELECT CAST([transOcurredOn] AS DATE) as Dategg, DATEPART(HH,transOcurredOn) as 'hour', z.hrcount COUNT(*) AS 'Trans count' FROM [tpTrans] cross join zz_temptable z WHERE [transOcurredOn] > '2016 -06-18' GROUP BY CAST([transOcurredOn] AS DATE) ,DATEPART(HH,transOcurredOn),z.hourcount ORDER BY Dategg,hour
  • 不,您不会将可能的时间与实际交易交叉加入。您将可能的小时数与可能的天数交叉加入,然后在日期和时间相等的情况下将结果与实际交易分开。

标签: sql-server select aggregate-functions


【解决方案1】:

您可以为日期创建一个calendar table,为小时创建一个tally table。在这些表之间使用CROSS JOIN 生成一天中所有可能日期的24 小时记录,然后将LEFT JOIN 你的表添加到该表上。最终查询看起来像

   SELECT c.Date as Dategg, t.num as 'hour',
            COUNT(transOcurredOn) AS 'Trans count'
   FROM Calendar c
   CROSS JOIN Tally t
   LEFT JOIN [tpTrans] 
            ON t.num = DATEPART(HH,transOcurredOn)
            AND c.Date = CONVERT(DATE, [transOcurredOn] )
    WHERE c.Date> '2016-06-18' and c.Date <= GETDATE()
        AND t.num <=24
    GROUP BY c.Date ,t.num
    ORDER BY c.Date, t.num

【讨论】:

    【解决方案2】:

    创建一个表值函数并调用它来创建一个日期和时间表;

    SELECT CONVERT(varchar(10),[Start_Date],101)'Date', DATEPART(HOUR,[Start_Date])'Hour' 
    FROM generateDateTable('1/1/2019','1/12/2019','hour',1)
    WHERE DATEPART(HOUR,[Start_Date]) >= 7
    

    函数定义;

    CREATE function [dbo].[generateDateTable] 
    (
    @start_date datetime
    , @end_date datetime
    , @datepart varchar(20) = 'day'
    , @step int = 1
    )
    returns @dates table 
    (
    start_date datetime, 
    end_date datetime
    )
    as
    begin
    if( @datepart in ('year', 'yy', 'yyyy', 'quarter', 'qq', 'q', 'month', 'mm', 'm', 
    'dayofyear', 'dy', 'y', 'day', 'dd', 'd', 'week', 'wk', 'ww') )
    begin
        set @start_date = cast(floor(cast(@start_date as float)) as datetime)
        set @end_date = cast(floor(cast(@end_date as float)) as datetime)
    end
    
    declare @new_start datetime
    
    while @start_date <= @end_date
    begin
        set @new_start = (case 
            when @datepart in ('year', 'yy', 'yyyy') then dateadd(yy, @step, @start_date)
            when @datepart in ('quarter', 'qq', 'q') then dateadd(qq, @step, @start_date)
            when @datepart in ('month', 'mm', 'm') then dateadd(mm, @step, @start_date) 
            when @datepart in ('dayofyear', 'dy', 'y') then dateadd(dy, @step, 
     @start_date) 
            when @datepart in ('day', 'dd', 'd') then dateadd(dd, @step, @start_date) 
            when @datepart in ('week', 'wk', 'ww') then dateadd(ww, @step, @start_date) 
            when @datepart in ('hour', 'hh') then dateadd(hh, @step, @start_date) 
            when @datepart in ('minute', 'mi', 'n') then dateadd(n, @step, @start_date) 
            when @datepart in ('second', 'ss', 's') then dateadd(s, @step, @start_date) 
            when @datepart in ('millisecond', 'ms') then dateadd(ms, @step, @start_date) 
            else dateadd(dd, @step, @start_date)
        end)
            insert 
                @dates 
            (
              start_date
            , end_date
            ) values (
                @start_date
                , dateadd(ms, -3, @new_start)
            )
            set @start_date = @new_start
        end
        return 
    end
    

    【讨论】:

      猜你喜欢
      • 2010-12-08
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 2015-07-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多