如何在T-SQL中获得所需的结果.... 喜欢 我有像
这样的记录UseriD InDate outDate
1 3/12/2010 3/12/2010
1 3/12/2010 3/13/2010
1 3/19/2010 3/30/2010
2 3/2/2010 3/3/2010
2 3/3/2010 3/4/2010
2 3/4/2010 3/29/2010
3 2/2/2010 2/28/2010
所以我们的结果必须像这样
UseriD InDate outDate
1 3/12/2010 3/13/2010
1 3/19/2010 3/30/2010
2 3/2/2010 3/29/2010
3 2/2/2010 2/28/2010
我们怎么做才是T-Sql
答案 0 :(得分:1)
我想分享我的解决方案,以帮助遇到同样问题的任何人:
/****** Object: StoredProcedure [dbo].[MergeSeqDates] Script Date: 06/12/2010 18:18:26 ******/
/************************************************************************************************
THIS STORED PROCEDURE CAN BE USED FOR AN INPUT TABLE LIKE THE FOLLOWING
tablename: [_dateSeq]
UserId InDate OutDate id Record number
1 3/12/2010 12:00:00 AM 3/12/2010 12:00:00 AM 1
1 3/12/2010 12:00:00 AM 3/13/2010 12:00:00 AM 2
1 3/19/2010 12:00:00 AM 3/30/2010 12:00:00 AM 3
2 3/2/2010 12:00:00 AM 3/3/2010 12:00:00 AM 4
2 3/3/2010 12:00:00 AM 3/4/2010 12:00:00 AM 5
2 3/4/2010 12:00:00 AM 3/9/2010 12:00:00 AM 6
3 2/2/2010 12:00:00 AM 2/28/2010 12:00:00 AM 7
TO GIVE AN OUTPUT TABLE LIKE:
tablename: [mergeddateseq]
UserId InDate OutDate Unique_Id
1 3/12/2010 12:00:00 AM 3/13/2010 12:00:00 AM 1
1 3/19/2010 12:00:00 AM 3/30/2010 12:00:00 AM 2
2 3/2/2010 12:00:00 AM 3/9/2010 12:00:00 AM 3
3 2/2/2010 12:00:00 AM 2/28/2010 12:00:00 AM 4
Table Structures used:
(1)
CREATE TABLE [dbo].[_dateSeq](
[UserId] [bigint] NULL,
[InDate] [datetime] NULL,
[OutDate] [datetime] NULL,
[id] [bigint] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK__dateSeq] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
(2)
CREATE TABLE [dbo].[MergedDateSeq](
[Unique_Id] [bigint] IDENTITY(1,1) NOT NULL,
[UserId] [bigint] NULL,
[InDate] [datetime] NULL,
[OutDate] [datetime] NULL,
CONSTRAINT [PK_MergedDateSeq] PRIMARY KEY CLUSTERED
(
[Unique_Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
************************************************************************************************/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[MergeSeqDates]
(
@StartDate datetime,
@EndDate datetime
)
AS
BEGIN
/*Clear the output table before new data is put into it*/
DROP TABLE mergeddateseq;
CREATE TABLE [dbo].[MergedDateSeq](
[Unique_Id] [bigint] IDENTITY(1,1) NOT NULL,
[UserId] [bigint] NULL,
[InDate] [datetime] NULL,
[OutDate] [datetime] NULL,
CONSTRAINT [PK_MergedDateSeq] PRIMARY KEY CLUSTERED
(
[Unique_Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
/*For every record in the original table, check if the user's next start date is consequent to the user's previous end date*/
/*If yes, update the earlier record*/
/*If not, add a new record record*/
DECLARE rec_cursor CURSOR FOR
SELECT UserId,InDate,OutDate FROM [_dateSeq] WHERE InDate>=@StartDate and ((OutDate<=@EndDate) or (OutDate is null)) order by InDate;
OPEN rec_cursor
Declare @DateFrom DateTime
Declare @DateTo DateTime
Declare @CardId bigint
Declare @mrgDateFrom DateTime
Declare @mrgDateTo DateTime
Declare @mrgCardId bigint
Declare @Unque_Id bigint
FETCH NEXT FROM rec_cursor
INTO @CardId,@DateFrom, @DateTo
WHILE @@FETCH_STATUS = 0
BEGIN
set @Unque_Id=0;
SELECT @Unque_Id=Unique_Id,@mrgCardId=UserId,@mrgDateFrom=InDate,@mrgDateTo=OutDate FROM mergeddateseq where UserId=@CardId order by OutDate desc;
if @@rowcount>0
BEGIN
--check dates
--update record if date is same
if (@DateFrom=@mrgDateTo)
Update mergeddateseq set OutDate=@DateTo where Unique_Id=@Unque_Id;
--update record if dates are sequential
else if (@DateFrom=DATEADD(day,+1,@mrgDateTo))
Update mergeddateseq set OutDate=@DateTo where Unique_Id=@Unque_Id;
else
--insert new record
Insert into mergeddateseq (UserId,InDate,OutDate) values (@CardId,@DateFrom,@DateTo);
END
else
BEGIN
--insert new record
Insert into mergeddateseq (UserId,InDate,OutDate) values (@CardId,@DateFrom,@DateTo);
END
FETCH NEXT FROM rec_cursor
INTO @CardId,@DateFrom, @DateTo
END
CLOSE rec_cursor
DEALLOCATE rec_cursor
Select * from mergeddateseq;
END
--exec [MergeSeqDates] @StartDate='1-1-2010', @EndDate='1-1-2011'
答案 1 :(得分:0)
也许是这样的:
SELECT UseriD, InDate, MAX(outDate)
FROM TABLE
GROUP BY UseriD, InDate
ORDER BY UseriD, InDate
这将选择所有唯一的UseriD, InDate
组合,并显示与该组合匹配的最新outDate
。例如有2行有UseriD = 1和InDate = 3/12/2010,但outDates是2010年3月12日和2010年3月13日,因此该用户的最大(outDate),InDate分组将显示{{1} }。
答案 2 :(得分:0)
可能是一个两步过程。 首先使用UserId,InDat,OutDate创建临时工作表。然后 插入工作表(userid,inDate)从UserId,InDate
中选择UserId,来自InputTable组的InDate然后下一步将是
更新工作台 设置outdate = t.outdate from(select userid,OutDate from InputTable group by userid,outDate)as t UserId = t.UserId
我没有尝试过最后一个语句,但您应该能够动态创建虚拟表并更新主表。如果它不起作用,那么为每个用户每个日期创建一个OutDate的第二个工作表,然后在两个工作表之间创建一个连接。