根据第二个表

时间:2016-11-28 07:44:04

标签: sql-server

我有一个表(tbl_user),其中包含用户(userid)的开头(start)和结束(end)日期。我想创建第二个表(tbl_minutes),每个用户的开始和结束之间的所有分钟(每分钟由userid标识)。这意味着在第二个表中我为每个用户提供了开始和结束之间的所有分钟。怎么办呢?

我尝试使用视图(见下文)。但服务器无法完成它并中止。似乎太复杂了。

SELECT TOP (100) PERCENT dbo.view_users_woid.userID, dbo.view_users_woid.startdate, 
dbo.view_users_woid.enddate, dbo.view_minutes.datetime 
FROM dbo.view_minutes 
INNER JOIN dbo.view_users_woid 
 ON dbo.view_minutes.datetime >= dbo.view_users_woid.startdate
  AND dbo.view_minutes.datetime <= dbo.view_users_woid.enddate 
ORDER BY dbo.view_users_woid.userID, dbo.view_minutes.datetime 

5 个答案:

答案 0 :(得分:1)

您可以使用DATEDIFF计算两个日期之间的差异:

DATEDIFF(mi, date1, date2)

我假设您知道如何针对您的数据运行此函数并使用INSERT将其添加到第三个表,但如果没有,请给我一个喊叫。

答案 1 :(得分:0)

试试这样:

此函数将创建一个运行数字的派生表(最多10 ^ 9)无中断闪电

CREATE FUNCTION dbo.RunningNumbers
(
     @start INT
    ,@count INT
    ,@step INT
)
RETURNS TABLE
AS
RETURN
WITH x AS(SELECT 1 AS N FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tbl(N))--10^1
,N3 AS (SELECT 1 AS N FROM x CROSS JOIN x AS N2 CROSS JOIN x N3) --10^3
,Tally AS(SELECT TOP(@count) (ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) + @start -1) * @step AS Nr FROM N3 
          CROSS JOIN N3 N6 CROSS JOIN N3 AS N9)
SELECT Nr
FROM Tally;
GO

- 这是使用APPLY函数的方法。 CTE将首先缩短秒数:

DECLARE @tbl_user TABLE(UserID INT IDENTITY,startTime DATETIME,endTime DateTime,note VARCHAR(100));
INSERT INTO @tbl_user VALUES
 ({ts'2016-11-28 08:00:00'},{ts'2016-11-28 08:00:30'},'less than one') 
,({ts'2016-11-28 08:01:00'},{ts'2016-11-28 08:05:12'},'some minutes') 
,({ts'2016-11-28 23:50:00'},{ts'2016-11-29 00:10:23'},'over midnight');

WITH CutToNakedMinute AS
(
    SELECT UserID
          ,note
          ,CONVERT(DATETIME,CONVERT(VARCHAR(17),startTime,126)+'00',126) AS StartMinute
          ,CONVERT(DATETIME,CONVERT(VARCHAR(17),endTime,126)+'00',126) AS EndMinute
    FROM @tbl_user AS u
)
SELECT UserID
      ,note
      ,StartMinute
      ,DATEADD(MINUTE,steps.Nr,StartMinute) AS RunningMinute
FROM CutToNakedMinute
OUTER APPLY dbo.RunningNumbers(0,DATEDIFF(MINUTE,StartMinute,EndMinute)+1,1) AS steps
GO

--Clean-up for testing

DROP FUNCTION dbo.RunningNumbers;

结果

+--------+---------------+-------------------------+-------------------------+
| UserID | note          | StartMinute             | RunningMinute           |
+--------+---------------+-------------------------+-------------------------+
| 1      | less than one | 2016-11-28 08:00:00.000 | 2016-11-28 08:00:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 2      | some minutes  | 2016-11-28 08:01:00.000 | 2016-11-28 08:01:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 2      | some minutes  | 2016-11-28 08:01:00.000 | 2016-11-28 08:02:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 2      | some minutes  | 2016-11-28 08:01:00.000 | 2016-11-28 08:03:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 2      | some minutes  | 2016-11-28 08:01:00.000 | 2016-11-28 08:04:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 2      | some minutes  | 2016-11-28 08:01:00.000 | 2016-11-28 08:05:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-28 23:50:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-28 23:51:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-28 23:52:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-28 23:53:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-28 23:54:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-28 23:55:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-28 23:56:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-28 23:57:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-28 23:58:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-28 23:59:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-29 00:00:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-29 00:01:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-29 00:02:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-29 00:03:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-29 00:04:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-29 00:05:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-29 00:06:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-29 00:07:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-29 00:08:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-29 00:09:00.000 |
+--------+---------------+-------------------------+-------------------------+
| 3      | over midnight | 2016-11-28 23:50:00.000 | 2016-11-29 00:10:00.000 |
+--------+---------------+-------------------------+-------------------------+

答案 2 :(得分:0)

您可以尝试以下查询

Sheet3!A3

答案 3 :(得分:0)

一种方法是创建一个触发器,根据第一个表中的更改插入第二个表。

假设usertable具有以下数据

userid startdate   enddate
1       20161001   20161002

现在再次假设tbl_minutes的格式低于

userid startdate  enddate     mindata

触发器将采用以下格式

create trigger trg_test
on 
dbo.userid_test
after insert 
as
begin

;with cte
as
(
select userid,startdate,enddate,dateadd(mi,1,startdate)  as mindata from inserted i
union all
select userid,startdate,enddate,dateadd(mi,1,mindata) from
cte c
where dateadd(mi,1,mindata)<=enddate
)
insert  into dbo.tbl_minutes
select *
 from cte option(maxrecursion 0)

 end

输出:

userid  startdate            enddate               mindata
1   2016-10-01 00:00:00.000 2016-10-02 00:00:00.000 2016-10-01 03:38:00.000

当然,您必须注意修改更新触发器

答案 4 :(得分:0)

这是我的解决方案,它完美无缺:

declare @user_id int

select @user_id = min( userid ) from tbl_users

while @user_id is not null
begin
    declare @maxmin int
    declare @patid int
    declare @minute as datetime
    declare @iter2 int
    declare @dateandtime datetime
    set @maxmin=(select DATEDIFF(mi, AddmissionDate, DischargeDate) from tbl_users where userid = @user_id)
    set @patid=(select userid from tbl_users where userid = @user_id)
    set @dateandtime=(select addmissiondate from tbl_users where userid = @user_id)
    set @iter2=0

    while @iter2 <= @maxmin

        BEGIN

        insert into tbl_users_minutes(userid,dateandtime) 
        values (@patid,DATEADD(mi,@iter2,@dateandtime))

        SET @Iter2 = @Iter2 + 1

    END

select @user_id = min( userid ) from tbl_users where userid > @user_id


end

我在google搜索并浏览各种网站后创建了它。 感谢各位的帮助。