我试图在每行的基础上确定在特定时刻存在多少这些请求。
日期和时间专门用于在结果中以这种方式显示,但它们分别以默认yyyy-mm-dd
和00:00:00.000
格式存储在数据库中
Request Data:
ID | CDate | CTime | LDate | LTime
---------------------------------------------------------------
230700 | 13/07/2016 | 6:52am | 13/07/2016 | 7:21am
746970 | 13/07/2016 | 7:05am | 13/07/2016 | 7:10am
746971 | 13/07/2016 | 7:09am | 13/07/2016 | 7:09am
746972 | 13/07/2016 | 7:16am | 13/07/2016 | 7:27am
746973 | 13/07/2016 | 7:20am | 13/07/2016 | 7:29am
CTime
指的是问题创建时间,LTime
指的是用户登录问题的时间。
我希望根据整个查询的结果在这些结果的末尾添加一个新列。新列将计算在任何给定时间可见的问题数量。问题在创建后立即可见,并在用户登录请求时消失,创建LTime
条目。
在此示例中,我们将使用ID: 746970
的第二行数据。我们可以看到创建时间为7:05am
,但问题直到7:10am
才会登录。在该登录时间,已经创建了2个其他问题,但尚未登录(230700
和746971
),创建时间为6:52am
/ {{1} }和7:21am
/ 7:09am
分别。因此,新列将报告登录时可见问题数量的7:09am
值。
到目前为止,我的思维过程让我相信这需要2-3部分查询,可能会将结果存储在临时表中。查询的第一部分将获得上面显示的结果(已创建)。查询的第二部分将在“每行”的基础上确定有多少行3
小于每行的CTime
。然后,第三个查询将对第二个查询的结果运行另一个检查,以计算当前行的LTime
等于或小于其他行的LTime
的行数。
运行此操作后的结果如下所示。 方括号内的文字不会显示在结果中,只是包含在显示效果中。
LTime
New data:
我对这一点感到茫然,我知道它的逻辑,但不能为我的生活把它放到MS SQL代码中。非常感谢任何帮助。
答案 0 :(得分:0)
我要说的第一件事是你应该考虑改变你的表格,使得DATE和TIME字段不是分开的。除非您运行一大堆仅关心时间或仅关心日期的查询,并且您已经围绕此建立了索引,否则最好使用单个DATETIME列 - 它使运行的查询更加容易,同时需要日期和时间。
继续我认为是你的问题的解决方案(假设“活动”的标准是正确的)......简短的回答是你不需要任何临时表或任何东西(我的解决方案使用CTE但它甚至不需要那样):
DECLARE @ TABLE (ID INT PRIMARY KEY, CDate DATE NOT NULL, CTime TIME NOT NULL, LDate DATE NOT NULL, LTime TIME NOT NULL)
INSERT @ VALUES (230700, '2016-07-13', '06:52:00.000', '2016-07-13', '07:21:00.000')
, (746970, '2016-07-13', '07:05:00.000', '2016-07-13', '07:10:00.000')
, (746971, '2016-07-13', '07:09:00.000', '2016-07-13', '07:09:00.000')
, (746972, '2016-07-13', '07:16:00.000', '2016-07-13', '07:27:00.000')
, (746973, '2016-07-13', '07:20:00.000', '2016-07-13', '07:29:00.000');
WITH CTE AS (
SELECT ID
, CDate + CAST(CTime AS DATETIME) CDateTime
, LDate + CAST(LTime AS DATETIME) LDateTime
FROM @)
SELECT T.ID, T.CDateTime, T.LDateTime, Z.ActiveCount
FROM CTE T
OUTER APPLY (
SELECT CAST(COUNT(*) AS VARCHAR(255))
+ ' (' +
STUFF((SELECT ', ' + CAST(ID AS VARCHAR(255))
FROM CTE
WHERE CDateTime <= T.LDateTime
AND LDateTime >= T.LDateTime
ORDER BY ID
FOR XML PATH ('')), 1, 2, '') + ')'
-- COUNT(*) -- this just produces the number
FROM CTE
WHERE CDateTime <= T.LDateTime
AND LDateTime >= T.LDateTime) Z(ActiveCount)
如果您需要将日期和时间字段分开,则可以将该语句重写为:
DECLARE @ TABLE (ID INT PRIMARY KEY, CDate DATE NOT NULL, CTime TIME NOT NULL, LDate DATE NOT NULL, LTime TIME NOT NULL)
INSERT @ VALUES (230700, '2016-07-13', '06:52:00.000', '2016-07-13', '07:21:00.000')
, (746970, '2016-07-13', '07:05:00.000', '2016-07-13', '07:10:00.000')
, (746971, '2016-07-13', '07:09:00.000', '2016-07-13', '07:09:00.000')
, (746972, '2016-07-13', '07:16:00.000', '2016-07-13', '07:27:00.000')
, (746973, '2016-07-13', '07:20:00.000', '2016-07-13', '07:29:00.000');
SELECT T.ID
, CONVERT(VARCHAR(255), T.CDate, 103) CDate
, CONVERT(VARCHAR(255), T.CTime, 100) CTime
, CONVERT(VARCHAR(255), T.LDate, 103) LDate
, CONVERT(VARCHAR(255), T.LTime, 100) LTime
, Z.ActiveCount
FROM @ T
OUTER APPLY (
SELECT COUNT(*) -- this just produces the number
FROM @
WHERE CDate + CAST(CTime AS DATETIME) <= T.LDate + CAST(T.LTime AS DATETIME)
AND LDate + CAST(LTime AS DATETIME) >= T.LDate + CAST(T.LTime AS DATETIME)) Z(ActiveCount)