按日期添加计数器,每天将用户添加到查询中

时间:2016-08-30 08:02:54

标签: sql sql-server

我有一个数据表,可以将扫描结果存储到建筑物中,这包含超过一百万行的数据。我正在尝试在此查询中添加临时状态列,每天计算扫描数。出于此问题的目的,我们将其用作主数据表:

CREATE TABLE DataTable (DataTableID INT IDENTITY(1,1) NOT NULL,
User VARCHAR(50),
EventTime DATETIME)

由此我将其缩小以仅显示今天的扫描:

SELECT * FROM DataTable 
WHERE CONVERT(DATE,EventTime) = CONVERT(DATE, SYSDATETIME())

此时我想在上面的查询中添加状态列。状态列:

  • ODD - 意味着
  • 的人
  • 偶然 - 意味着中的人>

    (这只是一个从1开始的整数字段,当天每次扫描将增加1, PER USER )。 我将如何做到这一点?

  • 我确实希望将此作为一个视图,因此值得一提,以防这会影响查询语法

  • 还值得一提的是,我无法在主表中添加状态列,因为这会阻止门访问程序的工作,否则我会在这里添加一些东西来控制它。

示例数据:

DataTableID         User            EventTime              Status
     1              Joe             30/08/2016 09:00:00      1
     2              Alan            30/08/2016 08:45:00      1
     3              John            30/08/2016 09:02:00      1
     4              Steven          30/08/2016 07:30:00      1
     5              Joe             30/08/2016 11:00:00      2
     6              Mike            30/08/2016 17:30:00      1
     7              Joe             30/08/2016 12:00:00      3

2 个答案:

答案 0 :(得分:1)

你想要一个简单的窗口函数。请查看下面的查询,如果您有任何疑问,请与我们联系。对于窗口化,它由EventTime而不是DataTableID排序,然后在最终查询中由DataTableID排序。如果您的数据在表格中的顺序不正确,这将确保您不会遇到任何问题。

用于测试的临时表;

CREATE TABLE #DataTable 
(DataTableID INT IDENTITY(1,1) NOT NULL,
[User] VARCHAR(50),
EventTime DATETIME)

填写样本数据;

INSERT INTO #DataTable
VALUES
 ('Joe', '2016-08-30 09:00:00')
,('Alan', '2016-08-30 08:45:00')
,('John', '2016-08-30 09:02:00')
,('Steven', '2016-08-30 07:30:00')
,('Joe', '2016-08-30 11:00:00')
,('Mike', '2016-08-30 17:30:00')
,('Joe', '2016-08-30 12:00:00')

查询

SELECT 
DataTableID
,[User]
,EventTime
,ROW_NUMBER() OVER(PARTITION BY [User] ORDER BY EventTime) Status
FROM #DataTable 
WHERE CONVERT(DATE,EventTime) = CONVERT(DATE, SYSDATETIME())
ORDER BY DataTableID

输出

DataTableID User    EventTime               Status
1           Joe     2016-08-30 09:00:00.000 1
2           Alan    2016-08-30 08:45:00.000 1
3           John    2016-08-30 09:02:00.000 1
4           Steven  2016-08-30 07:30:00.000 1
5           Joe     2016-08-30 11:00:00.000 2
6           Mike    2016-08-30 17:30:00.000 1
7           Joe     2016-08-30 12:00:00.000 3

答案 1 :(得分:1)

类似的东西:

select *, row_number() over(partition by user, cast(eventtime as date) order by eventtime) as status
from datatable

应该这样做。

但是,我建议创建一个计算列作为强制转换(eventtime作为日期),并在此和用户列以及原始事件时间列上创建复合索引以及性能原因。