SQL Server PARA CADA Bucle
Tengo la siguiente consulta SQL:
DECLARE @MyVar datetime = '1/1/2010'
SELECT @MyVar
Esto, naturalmente, devuelve '1/1/2010'.
Lo que quiero hacer es tener una lista de fechas, digamos:
1/1/2010
2/1/2010
3/1/2010
4/1/2010
5/1/2010
Entonces quiero PARA CADA uno a través de los números y ejecutar la consulta SQL.
Algo así como (pseudocódigo):
List = 1/1/2010,2/1/2010,3/1/2010,4/1/2010,5/1/2010
For each x in List
do
DECLARE @MyVar datetime = x
SELECT @MyVar
Así que esto regresaría: -
1/1/2010 2/1/2010 3/1/2010 4/1/2010 5/1/2010
Quiero que esto devuelva los datos como un conjunto de resultados, no varios conjuntos de resultados, por lo que puede que necesite usar algún tipo de unión al final de la consulta, por lo que cada iteración del bucle se une al siguiente.
Editar
Tengo una consulta grande que acepta un parámetro 'to date', necesito ejecutarlo 24 veces, cada vez con una fecha específica que necesito poder suministrar (estas fechas van a ser dinámicas) Quiero evitar repetir mi consulta 24 veces con union alls uniéndolas como si tuviera que volver y agregar columnas adicionales sería muy lento.
7 answers
SQL es principalmente un lenguaje orientado a conjuntos-generalmente es una mala idea usar un bucle en él.
En este caso, se podría lograr un resultado similar usando un CTE recursivo:
with cte as
(select 1 i union all
select i+1 i from cte where i < 5)
select dateadd(d, i-1, '2010-01-01') from cte
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-29 08:59:55
Aquí hay una opción con una variable de tabla:
DECLARE @MyVar TABLE(Val DATETIME)
DECLARE @I INT, @StartDate DATETIME
SET @I = 1
SET @StartDate = '20100101'
WHILE @I <= 5
BEGIN
INSERT INTO @MyVar(Val)
VALUES(@StartDate)
SET @StartDate = DATEADD(DAY,1,@StartDate)
SET @I = @I + 1
END
SELECT *
FROM @MyVar
Puedes hacer lo mismo con una tabla temporal:
CREATE TABLE #MyVar(Val DATETIME)
DECLARE @I INT, @StartDate DATETIME
SET @I = 1
SET @StartDate = '20100101'
WHILE @I <= 5
BEGIN
INSERT INTO #MyVar(Val)
VALUES(@StartDate)
SET @StartDate = DATEADD(DAY,1,@StartDate)
SET @I = @I + 1
END
SELECT *
FROM #MyVar
Deberías decirnos cuál es tu objetivo principal, como dijo @JohnFx, esto probablemente podría hacerse de otra manera (más eficiente).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-24 15:22:23
Podría usar una tabla de variables, como esta:
declare @num int
set @num = 1
declare @results table ( val int )
while (@num < 6)
begin
insert into @results ( val ) values ( @num )
set @num = @num + 1
end
select val from @results
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-16 21:46:41
Este tipo de depende de lo que desea hacer con los resultados. Si estás justo después de los números, una opción basada en conjuntos sería una tabla de números , que es útil para todo tipo de cosas.
Para MSSQL 2005+, puede usar un CTE recursivo para generar una tabla de números en línea:
;WITH Numbers (N) AS (
SELECT 1 UNION ALL
SELECT 1 + N FROM Numbers WHERE N < 500
)
SELECT N FROM Numbers
OPTION (MAXRECURSION 500)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-24 14:57:21
declare @counter as int
set @counter = 0
declare @date as varchar(50)
set @date = cast(1+@counter as varchar)+'/01/2013'
while(@counter < 12)
begin
select cast(1+@counter as varchar)+'/01/2013' as date
set @counter = @counter + 1
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-06 18:40:33
[CREATE PROCEDURE [rat].[GetYear]
AS
BEGIN
-- variable for storing start date
Declare @StartYear as int
-- Variable for the End date
Declare @EndYear as int
-- Setting the value in strat Date
select @StartYear = Value from rat.Configuration where Name = 'REPORT_START_YEAR';
-- Setting the End date
select @EndYear = Value from rat.Configuration where Name = 'REPORT_END_YEAR';
-- Creating Tem table
with [Years] as
(
--Selecting the Year
select @StartYear [Year]
--doing Union
union all
-- doing the loop in Years table
select Year+1 Year from [Years] where Year < @EndYear
)
--Selecting the Year table
selec]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-19 12:39:17
Por supuesto una vieja pregunta. Pero tengo una solución simple donde no hay necesidad de bucle, CTE, variables de tabla, etc.
DECLARE @MyVar datetime = '1/1/2010'
SELECT @MyVar
SELECT DATEADD (DD,NUMBER,@MyVar)
FROM master.dbo.spt_values
WHERE TYPE='P' AND NUMBER BETWEEN 0 AND 4
ORDER BY NUMBER
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-24 06:58:03