Le plus simple c'est de passer par un pivot et une fonction fenêtré, tu peux ce faisant te passer de procédure stocker ou autres artifices.
pour commencé, on va numéroter les lignes
on as par exemple:
Emp1 2013-01-01 10:01
Emp2 2013-01-01 10:53
Emp1 2013-01-01 11:45
Emp2 2013-01-01 12:10
Emp1 2013-01-02 09:37
Emp1 2013-01-02 11:58
Emp1 2013-01-02 13:10
Emp1 2013-01-02 17:53
on veux numéroté les lignes dans l'ordre croissant des heures pour chaque couple date/employé :
Emp1 2013-01-01 10:01 1
Emp1 2013-01-01 11:45 2
Emp1 2013-01-02 09:37 1
Emp1 2013-01-02 11:58 2
Emp1 2013-01-02 13:10 3
Emp1 2013-01-02 17:53 4
Emp2 2013-01-01 10:53 1
Emp2 2013-01-01 12:10 2
pour se faire on utilise la function ROW_NUMBER() OVER(...)
SELECT
[matric],
[date],
[heure],
ROW_NUMBER() OVER (PARTITION BY [matric],[date] ORDER BY [heure]) AS P
FROM [dbo].[Pointage]
Ensuite on va pivoter le résultat de cette première requette, les numéros qu'on viens de calculer vont devenir des noms de colonnes qui contiendrons l’horaire associé, en groupant le tout suivant les autres champs de la requette,
SELECT
[PVT].[matric],
[PVT].[date],
[PVT].[1] AS [P1],
[PVT].[2] AS [P2],
[PVT].[3] AS [P3],
[PVT].[4] AS [P4],
[PVT].[5] AS [P5],
[PVT].[6] AS [P6],
[PVT].[7] AS [P7],
[PVT].[8] AS [P8],
[PVT].[9] AS [P9],
[PVT].[10] AS [P10],
[PVT].[11] AS [P11],
[PVT].[12] AS [P12],
[PVT].[13] AS [P13],
[PVT].[14] AS [P14],
[PVT].[15] AS [P15],
[PVT].[16] AS [P16]
FROM (
SELECT
[matric],
[date],
[heure],
ROW_NUMBER() OVER (PARTITION BY [matric],[date] ORDER BY [heure]) AS P
FROM [dbo].[Pointage]
) AS [SRC]
PIVOT (
MIN([heure])
FOR [P] IN ( [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16])
) AS [PVT]
Pour amélioré la rapidité de la requette, un index sur la table est le bienvenue (surtout si elle grossi bien...) :
CREATE NONCLUSTERED INDEX [IX_Pivot_Helper] ON [dbo].[Pointage]
(
[matric] ASC,
[date] ASC,
[heure] ASC
)
Pour finir, si tu ne veux pas réécrire cette requette pense à en faire une Vue :
CREATE VIEW [Pointage_Pivoter] AS
SELECT
[PVT].[matric],
[PVT].[date],
[PVT].[1] AS [P1],
[PVT].[2] AS [P2],
[PVT].[3] AS [P3],
[PVT].[4] AS [P4],
[PVT].[5] AS [P5],
[PVT].[6] AS [P6],
[PVT].[7] AS [P7],
[PVT].[8] AS [P8],
[PVT].[9] AS [P9],
[PVT].[10] AS [P10],
[PVT].[11] AS [P11],
[PVT].[12] AS [P12],
[PVT].[13] AS [P13],
[PVT].[14] AS [P14],
[PVT].[15] AS [P15],
[PVT].[16] AS [P16]
FROM (
SELECT
[matric],
[date],
[heure],
ROW_NUMBER() OVER (PARTITION BY [matric],[date] ORDER BY [heure]) AS P
FROM [dbo].[Pointage]
) AS [SRC]
PIVOT (
MIN([heure])
FOR [P] IN ( [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16])
) AS [PVT]
Tu n'auras plus qu'as utilisé la requette suivante :
SELECT * FROM [Pointage_Pivoter] WHERE [matric] = 'Emp1'