Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 考虑不在时间范围内的记录_Sql_Sql Server_Sql Server 2005 - Fatal编程技术网

Sql 考虑不在时间范围内的记录

Sql 考虑不在时间范围内的记录,sql,sql-server,sql-server-2005,Sql,Sql Server,Sql Server 2005,我们正在查询一个RFID数据库,并计算每小时特定时间段的读取量。但当没有记录时,时间框架就不会显示出来,这是应该的。然而,我们想报告的是,在这段时间内没有任何记录 以下是查询: select date_tr, right('0000'+ convert(varchar,timeofday),2) + '00 - ' + right('0000'+ convert(varchar,timeofday+1),2) + '00' as timeofday, count(placa) reads fro

我们正在查询一个RFID数据库,并计算每小时特定时间段的读取量。但当没有记录时,时间框架就不会显示出来,这是应该的。然而,我们想报告的是,在这段时间内没有任何记录

以下是查询:

select
date_tr,
right('0000'+ convert(varchar,timeofday),2) + '00 - ' + right('0000'+ convert(varchar,timeofday+1),2) + '00' as timeofday,
count(placa) reads
from
(select distinct gi.placa,
convert(varchar(10), tr.inDate,101) as date_tr,
datepart(hour, tr.inDate) timeofday
from
RFIDTransaction tr, RFIDGeneralInformation gi
where
gi.tag = tr.tag 
and inDate between current_timestamp - 1 and current_timestamp
and inLoc = 'GATE IN'
and gi.removed = 0
and tr.removed = 0
group by convert(varchar(10), tr.inDate,101), datepart(hour, tr.inDate), gi.placa) xx
group by date_tr, timeofday
order by date_tr, timeofday
此查询的输出如下所示:

date_tr     timeofday      reads
01/19/2014  0500 - 0600    12
01/19/2014  0600 - 0700    15
01/19/2014  0800 - 0900    22
...
select
  intervals.interval,
  mytable.*
from
  mytable
right join (
  select '0000-0100' as interval
  union all
  select '0100-0200' as interval
  union all
  ...
  select '2300-2400' as interval ) intervals
on
  mytable.interval = intervals.interval
现在,我们需要显示时间范围0700-0800,读取为零

我该怎么做


非常感谢

最简单的方法是创建另一个预先填充了所有24个时间段的表,并与之进行连接:

Interval_ID Interval
    1       0000-0100
    2       0100-0200
...
执行外部联接,任何没有数据的间隔都将在“读取”中显示为空。如果需要,将它们转换为零

这是一种相当常见的约会技巧,没有理由不能用间隔来完成。有时,为了解决这类计数问题,甚至可以方便地创建一个只包含1到1000之间所有整数的列表的表

-更新-

如果无法创建要联接的表,可以尝试联接到查询中创建的集合。语法如下所示:

date_tr     timeofday      reads
01/19/2014  0500 - 0600    12
01/19/2014  0600 - 0700    15
01/19/2014  0800 - 0900    22
...
select
  intervals.interval,
  mytable.*
from
  mytable
right join (
  select '0000-0100' as interval
  union all
  select '0100-0200' as interval
  union all
  ...
  select '2300-2400' as interval ) intervals
on
  mytable.interval = intervals.interval

这是我脑子里想不出来的代码,但它应该能让你找到正确的方向。不是很优雅,但因为您只关心24个值,这也不算太糟糕。

最简单的方法是创建另一个预先填充了所有24个时间段的表,并使用它进行连接:

Interval_ID Interval
    1       0000-0100
    2       0100-0200
...
执行外部联接,任何没有数据的间隔都将在“读取”中显示为空。如果需要,将它们转换为零

这是一种相当常见的约会技巧,没有理由不能用间隔来完成。有时,为了解决这类计数问题,甚至可以方便地创建一个只包含1到1000之间所有整数的列表的表

-更新-

如果无法创建要联接的表,可以尝试联接到查询中创建的集合。语法如下所示:

date_tr     timeofday      reads
01/19/2014  0500 - 0600    12
01/19/2014  0600 - 0700    15
01/19/2014  0800 - 0900    22
...
select
  intervals.interval,
  mytable.*
from
  mytable
right join (
  select '0000-0100' as interval
  union all
  select '0100-0200' as interval
  union all
  ...
  select '2300-2400' as interval ) intervals
on
  mytable.interval = intervals.interval

这是我脑子里想不出来的代码,但它应该能让你找到正确的方向。不是很优雅,但因为您只关心24个值,这也不算太糟糕。

最简单的方法是创建另一个预先填充了所有24个时间段的表,并使用它进行连接:

Interval_ID Interval
    1       0000-0100
    2       0100-0200
...
执行外部联接,任何没有数据的间隔都将在“读取”中显示为空。如果需要,将它们转换为零

这是一种相当常见的约会技巧,没有理由不能用间隔来完成。有时,为了解决这类计数问题,甚至可以方便地创建一个只包含1到1000之间所有整数的列表的表

-更新-

如果无法创建要联接的表,可以尝试联接到查询中创建的集合。语法如下所示:

date_tr     timeofday      reads
01/19/2014  0500 - 0600    12
01/19/2014  0600 - 0700    15
01/19/2014  0800 - 0900    22
...
select
  intervals.interval,
  mytable.*
from
  mytable
right join (
  select '0000-0100' as interval
  union all
  select '0100-0200' as interval
  union all
  ...
  select '2300-2400' as interval ) intervals
on
  mytable.interval = intervals.interval

这是我脑子里想不出来的代码,但它应该能让你找到正确的方向。不是很优雅,但因为您只关心24个值,这也不算太糟糕。

最简单的方法是创建另一个预先填充了所有24个时间段的表,并使用它进行连接:

Interval_ID Interval
    1       0000-0100
    2       0100-0200
...
执行外部联接,任何没有数据的间隔都将在“读取”中显示为空。如果需要,将它们转换为零

这是一种相当常见的约会技巧,没有理由不能用间隔来完成。有时,为了解决这类计数问题,甚至可以方便地创建一个只包含1到1000之间所有整数的列表的表

-更新-

如果无法创建要联接的表,可以尝试联接到查询中创建的集合。语法如下所示:

date_tr     timeofday      reads
01/19/2014  0500 - 0600    12
01/19/2014  0600 - 0700    15
01/19/2014  0800 - 0900    22
...
select
  intervals.interval,
  mytable.*
from
  mytable
right join (
  select '0000-0100' as interval
  union all
  select '0100-0200' as interval
  union all
  ...
  select '2300-2400' as interval ) intervals
on
  mytable.interval = intervals.interval

这是我脑子里想不出来的代码,但它应该能让你找到正确的方向。虽然不优雅,但由于您只关心24个值,这也不算太糟糕。

这里有一个2005年的友好解决方案

;WITH t AS
(
  SELECT DISTINCT gi.placa, -- not sure that you really want distinct there
     d = DATEADD(DAY, DATEDIFF(DAY,0,tr.inDate),0), h = DATEPART(HOUR, tr.inDate)
  FROM dbo.RFIDTransaction AS tr
  INNER JOIN dbo.RFIDGeneralInformation AS gi
  ON tr.tag = gi.tag
  WHERE tr.inDate >= DATEADD(DAY, -1, CURRENT_TIMESTAMP)
    AND tr.inDate <  CURRENT_TIMESTAMP
    AND tr.removed = 0 AND gi.removed = 0
    AND tr.inLoc = 'GATE IN'
),
h(h) AS
(
  SELECT TOP (24) DATEADD(HOUR,-number,DATEADD(HOUR, DATEDIFF(HOUR,0,GETDATE()),0))
    FROM master.dbo.spt_values WHERE [type] = N'P' AND number > 0 
    ORDER BY number
),
s AS 
(
  SELECT 
    dh = h.h, 
    d = CONVERT(CHAR(10), h.h, 101), 
    hs = CONVERT(CHAR(2), h.h, 108), 
    he = CONVERT(CHAR(2), DATEADD(HOUR, 1, h.h), 108),
    c = COUNT(t.d) 
  FROM h LEFT OUTER JOIN t
  ON DATEADD(HOUR, t.h, t.d) >= h.h
  AND DATEADD(HOUR, t.h, t.d) < DATEADD(HOUR, 1, h.h)
  GROUP BY h.h
)
SELECT 
  date_tr = d, 
  timeofday = RIGHT('0' + hs,2) + '00 - ' + RIGHT('0' + he,2) + '00',
  reads = c
FROM s ORDER BY dh;

在2005年,你没有更多的工作要做,因为你不能利用
时间
。当我有更多的时间时,我将不得不重新讨论这个问题,我只是想表达一下让您开始的基本方法。

这是一个2005年的友好解决方案

;WITH t AS
(
  SELECT DISTINCT gi.placa, -- not sure that you really want distinct there
     d = DATEADD(DAY, DATEDIFF(DAY,0,tr.inDate),0), h = DATEPART(HOUR, tr.inDate)
  FROM dbo.RFIDTransaction AS tr
  INNER JOIN dbo.RFIDGeneralInformation AS gi
  ON tr.tag = gi.tag
  WHERE tr.inDate >= DATEADD(DAY, -1, CURRENT_TIMESTAMP)
    AND tr.inDate <  CURRENT_TIMESTAMP
    AND tr.removed = 0 AND gi.removed = 0
    AND tr.inLoc = 'GATE IN'
),
h(h) AS
(
  SELECT TOP (24) DATEADD(HOUR,-number,DATEADD(HOUR, DATEDIFF(HOUR,0,GETDATE()),0))
    FROM master.dbo.spt_values WHERE [type] = N'P' AND number > 0 
    ORDER BY number
),
s AS 
(
  SELECT 
    dh = h.h, 
    d = CONVERT(CHAR(10), h.h, 101), 
    hs = CONVERT(CHAR(2), h.h, 108), 
    he = CONVERT(CHAR(2), DATEADD(HOUR, 1, h.h), 108),
    c = COUNT(t.d) 
  FROM h LEFT OUTER JOIN t
  ON DATEADD(HOUR, t.h, t.d) >= h.h
  AND DATEADD(HOUR, t.h, t.d) < DATEADD(HOUR, 1, h.h)
  GROUP BY h.h
)
SELECT 
  date_tr = d, 
  timeofday = RIGHT('0' + hs,2) + '00 - ' + RIGHT('0' + he,2) + '00',
  reads = c
FROM s ORDER BY dh;

在2005年,你没有更多的工作要做,因为你不能利用
时间
。当我有更多的时间时,我将不得不重新讨论这个问题,我只是想表达一下让您开始的基本方法。

这是一个2005年的友好解决方案

;WITH t AS
(
  SELECT DISTINCT gi.placa, -- not sure that you really want distinct there
     d = DATEADD(DAY, DATEDIFF(DAY,0,tr.inDate),0), h = DATEPART(HOUR, tr.inDate)
  FROM dbo.RFIDTransaction AS tr
  INNER JOIN dbo.RFIDGeneralInformation AS gi
  ON tr.tag = gi.tag
  WHERE tr.inDate >= DATEADD(DAY, -1, CURRENT_TIMESTAMP)
    AND tr.inDate <  CURRENT_TIMESTAMP
    AND tr.removed = 0 AND gi.removed = 0
    AND tr.inLoc = 'GATE IN'
),
h(h) AS
(
  SELECT TOP (24) DATEADD(HOUR,-number,DATEADD(HOUR, DATEDIFF(HOUR,0,GETDATE()),0))
    FROM master.dbo.spt_values WHERE [type] = N'P' AND number > 0 
    ORDER BY number
),
s AS 
(
  SELECT 
    dh = h.h, 
    d = CONVERT(CHAR(10), h.h, 101), 
    hs = CONVERT(CHAR(2), h.h, 108), 
    he = CONVERT(CHAR(2), DATEADD(HOUR, 1, h.h), 108),
    c = COUNT(t.d) 
  FROM h LEFT OUTER JOIN t
  ON DATEADD(HOUR, t.h, t.d) >= h.h
  AND DATEADD(HOUR, t.h, t.d) < DATEADD(HOUR, 1, h.h)
  GROUP BY h.h
)
SELECT 
  date_tr = d, 
  timeofday = RIGHT('0' + hs,2) + '00 - ' + RIGHT('0' + he,2) + '00',
  reads = c
FROM s ORDER BY dh;

在2005年,你没有更多的工作要做,因为你不能利用
时间
。当我有更多的时间时,我将不得不重新讨论这个问题,我只是想表达一下让您开始的基本方法。

这是一个2005年的友好解决方案

;WITH t AS
(
  SELECT DISTINCT gi.placa, -- not sure that you really want distinct there
     d = DATEADD(DAY, DATEDIFF(DAY,0,tr.inDate),0), h = DATEPART(HOUR, tr.inDate)
  FROM dbo.RFIDTransaction AS tr
  INNER JOIN dbo.RFIDGeneralInformation AS gi
  ON tr.tag = gi.tag
  WHERE tr.inDate >= DATEADD(DAY, -1, CURRENT_TIMESTAMP)
    AND tr.inDate <  CURRENT_TIMESTAMP
    AND tr.removed = 0 AND gi.removed = 0
    AND tr.inLoc = 'GATE IN'
),
h(h) AS
(
  SELECT TOP (24) DATEADD(HOUR,-number,DATEADD(HOUR, DATEDIFF(HOUR,0,GETDATE()),0))
    FROM master.dbo.spt_values WHERE [type] = N'P' AND number > 0 
    ORDER BY number
),
s AS 
(
  SELECT 
    dh = h.h, 
    d = CONVERT(CHAR(10), h.h, 101), 
    hs = CONVERT(CHAR(2), h.h, 108), 
    he = CONVERT(CHAR(2), DATEADD(HOUR, 1, h.h), 108),
    c = COUNT(t.d) 
  FROM h LEFT OUTER JOIN t
  ON DATEADD(HOUR, t.h, t.d) >= h.h
  AND DATEADD(HOUR, t.h, t.d) < DATEADD(HOUR, 1, h.h)
  GROUP BY h.h
)
SELECT 
  date_tr = d, 
  timeofday = RIGHT('0' + hs,2) + '00 - ' + RIGHT('0' + he,2) + '00',
  reads = c
FROM s ORDER BY dh;

在2005年,你没有更多的工作要做,因为你不能利用
时间
。当我有更多的时间时,我将不得不重新讨论这个问题,只是想表达让您开始的基本方法。

作为正确方向的一点,我倾向于使用一个基本表,它将提供适用日期/时间范围的列表,并将其用作主表,然后将其与可能不存在的结果左外连接。也就是说,请使用显式连接语法,除非您有充分的理由不这样做。这将使您或您的替代者更容易获得未来的支持作为正确方向的一点,我倾向于使用一个基表,它将提供适用日期/时间范围的列表,并将其用作主表,然后将其与可能不存在的结果左外连接。也就是说,请使用显式连接语法,除非您有充分的理由不这样做。这将使您或您的替代者更容易获得未来的支持作为正确方向的一点,我倾向于使用一个基表,它将提供适用日期/时间范围的列表,并将其用作主表,然后将其与可能不存在的结果左外连接。也就是说,请使用显式连接语法,除非您有充分的理由不这样做。它将使您或您的替代者更容易获得未来的支持