【问题标题】:MSSQL datetime datetime in phpphp中的MSSQL日期时间日期时间
【发布时间】:2016-11-14 15:24:23
【问题描述】:

我有一个问题,我认为存在几个解决方案。

场景 我已经建立了这个 Intranetpage,其中内部绩效 KPI​​ 对办公室是可见的。 数据从 MSSQL 数据库中提取并结合 PHP 显示在网页上,然后将数据转换为数组,以便 Google Chart API 可以从那里创建漂亮的图表。 到目前为止,一切都很好!

问题 我有一个图表,其中显示了过去 7 天创建的票证(以相反的顺序)。工单的数量由 MSSQL 计数创建,每天(今天 - 7 个)总共一个数字。

但在某些日子里,不会像周六或周日那样创建门票。那就是事情出错的地方。

今天是星期四,它显示:

Day          Amount
Thursday     25
Friday       10
Monday       30 (etc)
Tuesday      15 (day before) 
Wednesday    20 (yesterday)
Thursday     50 (today)

而不是

Saturday      0
Sunday        0
Monday       30
Tuesday      15
Wednesday    20
Thursday     50

问题是没有没有记录(票证)的创建日期在星期六或星期日,因此 MSSQL 无法对其进行计数。

PHP 计算图表中轴下方显示的日期(也是今天 -7),但 PHP 确实包括星期六和星期日,因此轴标题不代表轴显示的数据。

可能的解决方案 一种解决方案是 MSSQL 在结果表中以某种方式显示星期六和星期日。但我认为这是不可能的,因为这些记录根本不存在。

其他解决方案 检索 MSSQL 查询中使用的日期时间并将它们解析到我的 Intranetpage,以便谷歌图表可以显示这些日期而不是 PHP 创建的日期。但我得到一个“将日期时间类转换为字符串”错误。

因为 MSSQL 中的 datetime 是 datetime 类型而不是 varchar 类型。 在尝试了很多事情并在 google 和 stackoverflow 上进行了更多搜索之后,我可以成功地将 datetime 转换为 varchar。但比起我今天的日期并返回 7 天的部分,它不再起作用了。

我的 PHP(和查询)如下所示:


$sql = "                                                                

SELECT  top 7
    CAST(bb_casestartingtime AS DATE) AS DATE, COUNT(*) as TotalRows        
FROM
    CRM_MSCRM.dbo.FilteredIncident      
WHERE 
    bb_casestartingtime > (CONVERT(date, GETDATE() - 7))
GROUP BY CAST(bb_casestartingtime AS DATE)
Order by date

";

$stmt = sqlsrv_query( $conn, $sql );                                    
if( $stmt === false) {die( print_r( sqlsrv_errors(), true) );}

$x=5; 
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) 

    {   **$dateValue = date("Y-m-d", strtotime(" -$x day"));**
        echo "[',".$row[**date**].$row['TotalRows'].",],";
        $x--;   
    }

我把这两段代码分成了两半,但实际上它们是

表格看起来像这样(至少,有趣的部分):

case id   bb_casestartingtime
01        2016-11-10 15:30:45.000
02        2016-11-10 16:22:10.000
03        2016-11-09 15:02:15.000

我将按日期 (bb_casestartingtime) 的出现次数计算为总数。 所以今天我有 今天2条记录 昨天 1 条记录

现实问题 有人可以帮我提取查询中使用的日期时间吗?

我只使用 一个 表名为:FilteredIncident 有没有办法将日期时间 bb_casestartingtime 转换为 varchar(以便 PHP 可以提取它)但仍然计算每天的出现次数?

如果需要任何信息,请询问

提前致谢!

(我重写了我的整个问题,因为我匆忙写了最初的帖子)

【问题讨论】:

    标签: php sql-server count


    【解决方案1】:

    您可以通过创建一个日期范围表来实现您所追求的目标,您可以向它发送LEFT JOIN,这样您就可以在没有门票的日子获得0。您可以单独运行此代码进行测试,它应该会给您一些可以适应的东西:

    -- table for dummy data
    CREATE TABLE #FilteredIncident (bb_casestartingtime DATETIME)
    
    -- insert dummy data that has gaps and more than 7 days
    INSERT INTO #FilteredIncident
            ( bb_casestartingtime )
    VALUES  ( '20161110 12:00'),
            ( '20161110 11:00'),
            ( '20161109 10:00'),
            ( '20161108 13:00'),
            ( '20161107 09:00'),
            ( '20161104 07:00'),
            ( '20161104 05:00'),
            ( '20161104 16:00'),
            ( '20161103 18:00'),
            ( '20161103 19:00')
    
    -- create a date range table for last 7 days
    CREATE TABLE #DateRange ( DateVal Date )
    
    -- insert last 7 days
    INSERT INTO #DateRange
            ( DateVal )
    VALUES  ( GETDATE() )
           ,( DATEADD(D,-1,GETDATE()))
           ,( DATEADD(D,-2,GETDATE()))     
           ,( DATEADD(D,-3,GETDATE()))     
           ,( DATEADD(D,-4,GETDATE()))     
           ,( DATEADD(D,-5,GETDATE()))     
           ,( DATEADD(D,-6,GETDATE()))     
    
    -- SELECT * FROM #FilteredIncident -- uncomment to see data
    -- SELECT * FROM #DateRange        -- uncomment to see date range data
    
    SELECT COUNT(fi.bb_casestartingtime) TotalRows, dr.DateVal
    FROM #DateRange dr
    LEFT JOIN #FilteredIncident fi ON dr.DateVal = cast(fi.bb_casestartingtime AS DATE)
    GROUP BY dr.DateVal
    ORDER BY dr.DateVal
    
    DROP TABLE #FilteredIncident
    DROP TABLE #DateRange      
    

    生产:

    TotalRows   DateVal
    3           2016-11-04
    0           2016-11-05
    0           2016-11-06
    1           2016-11-07
    1           2016-11-08
    1           2016-11-09
    2           2016-11-10
    

    注意: 我建议将此 SQL 代码移动到存储过程中,而不是像你正在做的那样构建一个要执行的字符串。

    【讨论】:

    • 谢谢,这是我明天要尝试的第一件事,我现在不再工作,但谢谢你的回答。我会告诉你它是否有效。
    【解决方案2】:

    我通过工作解决了这个问题,因为我不需要看到有 0 张票的日子,我不需要建立一个临时表并进行左连接。

    我提出的解决方案是使用日期时间字段 (bb_casestartingtime) 并使用这些日期。现在图表轴标题与图表栏匹配。

    解决方案

    将 datetime 字段所在的 $variable 转换为 datetime 字段变量。

     $rows[] = "['".$row[1]->format('D j-m')."',".$row[0]."],";
                      ^               ^                ^
                The datetime row | The format | The amount of tickets
    

    【讨论】:

      猜你喜欢
      • 2011-11-11
      • 1970-01-01
      • 2013-06-16
      • 2015-08-05
      • 2013-01-05
      • 1970-01-01
      • 2016-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多