2010-06-12 2 views
0

Comment puis-je obtenir le résultat souhaité dans T-SQL comme .... comme J'ai un dossier commeComment puis-je obtenir le résultat souhaité dans T-SQL comme

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 

donc notre résultat doit comme ça

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 

Comment pouvons-nous faire est T-Sql

Répondre

1

Je voudrais partager ma solution pour aider toute personne qui vient en face du même problème:

/****** 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>[email protected] and ((OutDate<[email protected]) 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 [email protected] order by OutDate desc; 
    if @@rowcount>0 
     BEGIN 
     --check dates 
     --update record if date is same 
     if (@[email protected]) 
      Update mergeddateseq set [email protected] where [email protected]_Id; 
     --update record if dates are sequential 
     else if (@DateFrom=DATEADD(day,+1,@mrgDateTo)) 
      Update mergeddateseq set [email protected] where [email protected]_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' 
0

peut-être quelque chose comme ceci:

SELECT UseriD, InDate, MAX(outDate) 
FROM TABLE 
GROUP BY UseriD, InDate 
ORDER BY UseriD, InDate 

Ceci sélectionnera toutes les combinaisons uniques UseriD, InDate et affichera la dernière outDate correspondant à cette combinaison. par exemple. il y a 2 lignes qui ont UseriD = 1 et InDate = 3/12/2010, mais les outDates sont 3/12/2010 et 3/13/2010 donc max (outDate) pour ce UseriD, groupement InDate montrera 3/13/2010.

+0

ya, mais qu'en est le résultat de UserId 2 ?? – Azhar

+0

@Azhar Je suppose que vous avez besoin de quelque chose dans votre clause WHERE, en regardant éventuellement les colonnes qui ne sont pas dans la liste de sélection. Cette clause WHERE filtre très probablement les 2 autres lignes où UseriD = 2. Je pense que nous devons en savoir plus sur ce que vous essayez d'obtenir et sur les données des autres colonnes/tables que cette requête doit examiner. – krock

+0

non nous avons autant de données et nous devons le filtrer en conséquence – Azhar

0

Probablement un processus en deux étapes. Créez d'abord une table de travail temporaire avec UserId, InDat, OutDate. Puis insert table de travail (ID utilisateur, Indate) sélectionner UserId, Indate de groupe pouvant être entrés par UserId, Indate

Ensuite, l'étape suivante serait

mise à jour de table de travail ensemble outdate = t.outdate de (ID utilisateur de sélectionner, outdate du groupe InputTable par userid, outDate) comme t où UserId = t.UserId

Je n'ai pas essayé la dernière instruction mais vous devriez pouvoir créer une table virtuelle t à la volée et mettre à jour la table principale. Si cela ne fonctionne pas, créez une seconde table de travail pour le OutDate par utilisateur et par date, puis créez une jointure entre les deux tables de travail.

+0

ya, mais qu'en est-il du résultat de UserId 2 .. il ne serait pas gérer de cette façon :( – Azhar

Questions connexes