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
Libérer: 2025-01-10 11:52:41
original
877 Les gens l'ont consulté

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 :

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;
Copier après la connexion

Résultat :

客人日期
Bob2011-07-14
Bob2011-07-15
Bob2011-07-16
Bob2011-07-17

Extension de collecte :

Cette technique peut être étendue à un jeu de données à l'aide de la requête suivante :

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.退房日期;
Copier après la connexion

Résultat :

会员日期
Bob2011-07-14
Bob2011-07-15
Bob2011-07-16
Bob2011-07-17
Sam2011-07-12
Sam2011-07-13
Sam2011-07-14
Sam2011-07-15
Jim2011-07-16
Jim2011-07-17
Jim2011-07-18
Jim2011-07-19

Simplifié :

Comme @Dems l'a souligné, cette requête peut être encore simplifiée :

;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.退房日期);
Copier après la connexion

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 de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal