SQL - Ciclo que actualice un contador con referencia a otra columna

 
Vista:

Ciclo que actualice un contador con referencia a otra columna

Publicado por JHONATAN (8 intervenciones) el 18/02/2019 17:46:49
Buenos días,

Agradezco su ayuda con el siguiente tema de SQL server.

Tengo una tabla con una columna que no tiene registros consecutivos (1,2,3,4,9), y el numero 4 y el 9 se puede repetir mas de una vez, cada paquete de información viene limitado empezando por 1 y terminando por 9, Espero obtener una columna que me genere un resultado consecutivo y agrupado (1,2,3,4,5,6,...), como muestro en la siguiente tabla (Columna_esperada):

ORIGEN COLUMNA_ESPERADA
1 1
2 1
3 1
4 1
4 1
4 1
9 1
9 1
1 2
2 2
3 2
4 2
4 2
9 2

Pense en hacerlo lo anterior por un ciclo for pero no soy muy experto en ciclos y no lo he podido solucionar. Agradezco mucho sus aportes.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Isaias
Val: 2.542
Oro
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Ciclo que actualice un contador con referencia a otra columna

Publicado por Isaias (1921 intervenciones) el 18/02/2019 19:46:19
Hola ¿que versión - edición de SQL Server?

Te dejo estas dos opciones

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
create table ciudades(
PAIS VARCHAR(20) not null,
CIUDAD VARCHAR(20) not null
)
GO
 
insert into ciudades(PAIS, CIUDAD)
values('MEXICO', 'MONTERREY')
insert into ciudades(PAIS, CIUDAD)
values('MEXICO', 'GUADALAJARA')
insert into ciudades(PAIS, CIUDAD)
values('MEXICO', 'DISTRITO FEDERAL')
insert into ciudades(PAIS, CIUDAD)
values('MEXICO', 'TIJUANA')
insert into ciudades(PAIS, CIUDAD)
values('ESPAÑA', 'VALENCIA')
insert into ciudades(PAIS, CIUDAD)
values('ESPAÑA', 'MADRID')
insert into ciudades(PAIS, CIUDAD)
values('ESPAÑA', 'BARCELONA')
insert into ciudades(PAIS, CIUDAD)
values('ITALIA', 'ROMA')
insert into ciudades(PAIS, CIUDAD)
values('ITALIA', 'MILAN')
GO
 
SELECT PAIS, (SELECT COUNT(*)
FROM ciudades AS I
WHERE I.PAIS=J.PAIS
AND I.CIUDAD>=J.CIUDAD) AS No
, CIUDAD
FROM ciudades AS J
ORDER BY PAIS, No
go
 
DROP TABLE ciudades
GO
------------------------------------------- Opcion con 2005 y superior
1
select row_number() over (partition by cod_oficina order by cod_oficina) rn, cod_oficina from #oficinas
COD_OFICINA | CORRELATIVO
OF001 | 1
OF001 | 2
OF001 | 3
OF002 | 1
OF002 | 2
OF002 | 3
OF002 | 4
OF003 | 1
OF003 | 2
OF003 | 3
OF003 | 4
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Ciclo que actualice un contador con referencia a otra columna

Publicado por JHO (8 intervenciones) el 19/02/2019 15:49:58
Hola

La versión es SQL Server 2014 Management Studio, agradezco tu interés y colaboración. pero las opciones que me mostraste no generan el resultado esperado.

El siguiente codigo genera una tabla en la que se ve mas claro el problema el campo (VALOR_INICIAL) es como viene el campo, (VALOR_ESPERADO) es el campo que tiene el valor al que pretendo llegar, (VALOR_FOR) es donde pretendo generar una actualización con un ciclo For o While. y la (FILA) es originada con Identity

--CREO TABLA INICIAL
CREATE TABLE T_EJEMPLO
(
VALOR_INICIAL SMALLINT NULL
,VALOR_ESPERADO INT NULL
,VALOR_FOR SMALLINT NULL
,FILA INT IDENTITY
)
;
GO
--INSERTO LOS VALORES
INSERT INTO T_EJEMPLO
VALUES
(0,0,NULL)
,(1,1,NULL)
,(2,1,NULL)
,(3,1,NULL)
,(4,1,NULL)
,(4,1,NULL)
,(4,1,NULL)
,(4,1,NULL)
,(9,1,NULL)
,(1,2,NULL)
,(2,2,NULL)
,(3,2,NULL)
,(4,2,NULL)
,(4,2,NULL)
,(4,2,NULL)
,(4,2,NULL)
,(4,2,NULL)
,(4,2,NULL)
,(4,2,NULL)
,(9,2,NULL)
,(9,2,NULL)
,(1,3,NULL)
,(2,3,NULL)
,(3,3,NULL)
,(4,3,NULL)
,(4,3,NULL)
,(4,3,NULL)
,(4,3,NULL)
,(9,3,NULL)
,(1,4,NULL)
,(2,4,NULL)
,(3,4,NULL)
,(4,4,NULL)
,(4,4,NULL)
,(4,4,NULL)
,(9,4,NULL)
,(1,5,NULL)
,(2,5,NULL)
,(3,5,NULL)
,(4,5,NULL)
,(4,5,NULL)
,(4,5,NULL)
,(4,5,NULL)
,(9,5,NULL)
;
GO


Los campos VALOR_FOR y VALOR_ESPERADO deben ser iguales al final.

A continuacion relaciono el CODIGO con el CICLO WHILE (el cual no esta solucionando mi problema).

Agradezco si saben como puedo completarlo o si hay otra opcion para hacer lo que requiero..... MUCHAS GRACIAS.



DECLARE @IntCant AS int
,@IntCont as int
,@FINAL AS INT
,@REFERENCIA AS INT


set @IntCont = 1
SET @REFERENCIA = 1
set @FINAL = 1
select @IntCant = count(*) from T_EJEMPLO



WHILE @IntCont <= @IntCant
BEGIN
SELECT

FILA
,VALOR_INICIAL
,VALOR_ESPERADO
,iif(VALOR_INICIAL = 0 ,0,IIF(VALOR_INICIAL = 1,@REFERENCIA,IIF(VALOR_INICIAL>1,@FINAL,NULL)))
from T_EJEMPLO
where fila=@IntCont

set @IntCont = @IntCont + 1
set @REFERENCIA = @REFERENCIA + 1
set @FINAL = @FINAL + 1
END
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Isaias
Val: 2.542
Oro
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Ciclo que actualice un contador con referencia a otra columna

Publicado por Isaias (1921 intervenciones) el 19/02/2019 17:15:10
¿No es esto lo que desea obtener?, en este caso, el valor de la columna "rn"

1
2
select row_number() over (partition by VALOR_ESPERADO order by VALOR_ESPERADO) rn, VALOR_ESPERADO
from T_EJEMPLO

rn VALOR_ESPERADO
1 0
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
1 2
2 2
3 2
4 2
5 2
6 2
7 2
8 2
9 2
10 2
11 2
12 2
1 3
2 3
3 3
4 3
5 3
6 3
7 3
8 3
1 4
2 4
3 4
4 4
5 4
6 4
7 4
1 5
2 5
3 5
4 5
5 5
6 5
7 5
8 5
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Ciclo que actualice un contador con referencia a otra columna

Publicado por JHONATAN (8 intervenciones) el 19/02/2019 17:48:00
Antes que nada quisiera agradecer tu tiempo ayudandome con el caso.

Pero la columna VALOR_ESPERADO es una columna que intencionalmente puse para que se viera el resultado que quiero obtener.

El objetivo es que para cada dato de la columna VALOR_INICIAL se le debe hacer la validacion y si es 0 se deja 0, si es 1 se deja un consecutivo que se aumentara en +1 cada vez q encuentre un 1 y si es diferente de 1 se debe dejar el valor actual del consecutivo.

El resultado al que quiero llegar es el que esta en la columna VALOR_ESPERADO por lo cual no lo puedo usar como parte de la solución del problema, es mas como para comparar que mi solución esta acorde a lo que necesito.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Isaias
Val: 2.542
Oro
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Ciclo que actualice un contador con referencia a otra columna

Publicado por Isaias (1921 intervenciones) el 19/02/2019 17:51:43
En mi ejemplo, VALOR_AGREGADO es "rn", ¿no es la solución?, muestre su solucion o denos un ejemplo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Ciclo que actualice un contador con referencia a otra columna

Publicado por JHONATAN (8 intervenciones) el 20/02/2019 23:10:13
Mi solucion fue la siguiente:

Se que no es una solución optima y en miles de lineas se demora bastante. Sabes como puedo optimizarla?

Yo estaba pensando en usar While dentro de While para no usar las tablas #CONTADOR ni #t_ejemplo_COPIA. Pero no se como

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
DECLARE @CONTADOR INT = 1
DECLARE @TOTAL INT = (SELECT COUNT(*) FROM t_ejemplo)
 
 
 
--CREO TABLA EJEMPLO COPIA
SELECT
 FILA
,valor_inicial
,valor_for
 
into #t_ejemplo_COPIA
FROM t_ejemplo
 
 
--CREO TABLA CONTADOR
CREATE TABLE #CONTADOR
(CONTADOR INT NULL)
INSERT INTO #CONTADOR
VALUES (0)
 
 
WHILE @CONTADOR <= @TOTAL
 
 
	BEGIN
 
	--actualizo en la tabla principal T_EJEMPLO segun la funcion logica iif, desde la tabla temporal creada
			UPDATE t_ejemplo
			SET valor_for = T1.CALCULADO
			FROM
			(SELECT
			 FILA
			,valor_inicial
			,IIF(valor_inicial = 0,0,(SELECT MAX(CONTADOR) FROM #CONTADOR)) AS CALCULADO
			FROM #t_ejemplo_COPIA
			WHERE FILA= (SELECT MIN(FILA) FROM #t_ejemplo_COPIA)
			) AS T1
			WHERE t_ejemplo.FILA = T1.FILA
 
	--elimino el primer registro de la tabla temporal para poder validar el segundo en el proximo ciclo y asi sucesivamente hasta n... veces
			DELETE FROM #t_ejemplo_COPIA
			WHERE FILA = (SELECT TOP(1) FILA FROM #t_ejemplo_COPIA ORDER BY FILA)
 
	--Si el valor_inicial del primer registro de la tabla temporal es 1  suma uno al contador y lo inserta en la tabla creada #contador, si no es 1 no hace nada.
 
			IF(SELECT TOP(1) valor_inicial FROM #t_ejemplo_COPIA ORDER BY FILA) = 1
			BEGIN
			INSERT INTO #CONTADOR
			VALUES ((SELECT MAX(CONTADOR)+1 FROM #CONTADOR))
			END
 
	SET @CONTADOR = @CONTADOR+1
 
	END
 
 
DROP TABLE #t_ejemplo_COPIA
DROP TABLE #CONTADOR
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar