Maison >base de données >tutoriel mysql >Comment générer efficacement des plages de dates pour plusieurs invités dans SQL Server ?
Génération de plages de dates SQL Server
Question :
Bien que l'invite implique de générer une plage de dates, elle semble davantage axée sur la création d'un tableau où chaque ligne représente chaque jour du séjour d'un client. Plus précisément, étant donné le nom d'un client, la date d'arrivée et la date de départ, l'objectif est de générer un tableau au format suivant :
('Bob', 7/14), ('Bob', 7/15), ('Bob', 7/16), ('Bob', 7/17)
Solution efficace :
La requête suivante est considérée comme une méthode efficace dans ce but spécifique et peut être plus performante que l'utilisation d'une table de recherche dédiée :
<code class="language-sql">DECLARE @start DATE, @end DATE; SELECT @start = '20110714', @end = '20110717'; ;WITH n AS ( SELECT TOP (DATEDIFF(DAY, @start, @end) + 1) n = ROW_NUMBER() OVER (ORDER BY [object_id]) FROM sys.all_objects ) SELECT 'Bob', DATEADD(DAY, n-1, @start) FROM n;</code>
Résultat :
客人 | 日期 |
---|---|
Bob | 2011-07-14 |
Bob | 2011-07-15 |
Bob | 2011-07-16 |
Bob | 2011-07-17 |
Extension de collecte :
Cette technique peut être étendue à un jeu de données à l'aide de la requête suivante :
<code class="language-sql">DECLARE @t TABLE ( 会员 NVARCHAR(32), 入住日期 DATE, 退房日期 DATE ); INSERT @t SELECT N'Bob', '20110714', '20110717' UNION ALL SELECT N'Sam', '20110712', '20110715' UNION ALL SELECT N'Jim', '20110716', '20110719'; ;WITH [range](d,s) AS ( SELECT DATEDIFF(DAY, MIN(入住日期), MAX(退房日期))+1, MIN(入住日期) FROM @t -- WHERE ? ), n(d) AS ( SELECT DATEADD(DAY, n-1, (SELECT MIN(s) FROM [range])) FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id]) FROM sys.all_objects) AS s(n) WHERE n <= (SELECT MAX(d) FROM [range]) ) SELECT t.会员, n.d FROM n CROSS JOIN @t AS t WHERE n.d BETWEEN t.入住日期 AND t.退房日期;</code>
Résultat :
会员 | 日期 |
---|---|
Bob | 2011-07-14 |
Bob | 2011-07-15 |
Bob | 2011-07-16 |
Bob | 2011-07-17 |
Sam | 2011-07-12 |
Sam | 2011-07-13 |
Sam | 2011-07-14 |
Sam | 2011-07-15 |
Jim | 2011-07-16 |
Jim | 2011-07-17 |
Jim | 2011-07-18 |
Jim | 2011-07-19 |
Simplifié :
Comme @Dems l'a souligné, cette requête peut être encore simplifiée :
<code class="language-sql">;WITH natural AS ( SELECT ROW_NUMBER() OVER (ORDER BY [object_id]) - 1 AS val FROM sys.all_objects ) SELECT t.会员, d = DATEADD(DAY, natural.val, t.入住日期) FROM @t AS t INNER JOIN natural ON natural.val <= DATEDIFF(DAY, t.入住日期, t.退房日期);</code>
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!