Maison >base de données >tutoriel mysql >Comment générer efficacement des plages de dates pour plusieurs invités dans SQL Server ?

Comment générer efficacement des plages de dates pour plusieurs invités dans SQL Server ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2025-01-10 11:52:41808parcourir

How to Efficiently Generate Date Ranges for Multiple Guests in 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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn