Update secuencial

21/03/2007 - 10:45 por José Luis Capel - Aicom | Informe spam
Hola,

Sigo con mis cuestiones de novato... Dada una tabla con un campo numérico
donde normalmente guardaremos un orden
correlativo. Algo así

Tabla: pruebas

cCodigo dFecha nContador
'00012' '01/09/2005' 1
'00013' '02/09/2005' 3
'00014' '01/09/2005' 4
'00015' '03/09/2005' 5
'00011' '04/09/2005' 6
'00010' '05/09/2005' 8

Quisiera saber si hay alguna manera de hacer un único update para conseguir
esto:

cCodigo dFecha nContador
'00012' '01/09/2005' 1
'00013' '02/09/2005' 2
'00014' '01/09/2005' 3
'00015' '03/09/2005' 4
'00011' '04/09/2005' 5
'00010' '05/09/2005' 6

Algo así:

UPDATE PRUEBAS SET nContador = nRow() //suponiendo que nRow() fuera una
función que devuelva un número consecutivo..

Saludos,
José Luis Capel

Preguntas similare

Leer las respuestas

#1 Rubén Vigón
21/03/2007 - 11:20 | Informe spam
Hola José Luis,

Pueses hacerlo con una pequeña subconsulta de tipo COUNT(*); prueba lo siguiente:

UPDATE TuTabla SET nContador = (SELECT COUNT(*) FROM TuTabla t2 WHERE t2.nContador <= TuTabla.nContador)
_______________________________________

cCodigo dFecha nContador
0012 2005-09-01 00:00:00 1
0013 2005-09-02 00:00:00 2
0014 2005-09-01 00:00:00 3
0015 2005-09-03 00:00:00 4
0011 2005-09-04 00:00:00 5
0010 2005-09-05 00:00:00 6

(6 filas afectadas)
_______________________________________

Un saludo!

Rubén Vigón
Microsoft MVP Visual Basic
http://vigon.mvps.org
Respuesta Responder a este mensaje
#2 José Luis Capel - Aicom
21/03/2007 - 11:42 | Informe spam
Rubén,

Fantástico... se aprende mucho con este grupo!!

Gracias,
José Luis Capel

"Rubén Vigón" escribió en el mensaje
news:
Hola José Luis,

Pueses hacerlo con una pequeña subconsulta de tipo COUNT(*); prueba lo
siguiente:

UPDATE TuTabla SET nContador = (SELECT COUNT(*) FROM TuTabla t2 WHERE
t2.nContador <= TuTabla.nContador)
_______________________________________

cCodigo dFecha nContador
0012 2005-09-01 00:00:00 1
0013 2005-09-02 00:00:00 2
0014 2005-09-01 00:00:00 3
0015 2005-09-03 00:00:00 4
0011 2005-09-04 00:00:00 5
0010 2005-09-05 00:00:00 6

(6 filas afectadas)
_______________________________________

Un saludo!

Rubén Vigón
Microsoft MVP Visual Basic
http://vigon.mvps.org
Respuesta Responder a este mensaje
#3 Maxi
21/03/2007 - 13:11 | Informe spam
Hola, es una lastima no conocer la version de SQLServer pero si es la 2005
podes ver la funcion row_number()


Salu2

Microsoft MVP SQL Server
Culminis Speaker

"José Luis Capel - Aicom" escribió en el mensaje
news:uR$
Hola,

Sigo con mis cuestiones de novato... Dada una tabla con un campo numérico
donde normalmente guardaremos un orden
correlativo. Algo así

Tabla: pruebas

cCodigo dFecha nContador
'00012' '01/09/2005' 1
'00013' '02/09/2005' 3
'00014' '01/09/2005' 4
'00015' '03/09/2005' 5
'00011' '04/09/2005' 6
'00010' '05/09/2005' 8

Quisiera saber si hay alguna manera de hacer un único update para
conseguir
esto:

cCodigo dFecha nContador
'00012' '01/09/2005' 1
'00013' '02/09/2005' 2
'00014' '01/09/2005' 3
'00015' '03/09/2005' 4
'00011' '04/09/2005' 5
'00010' '05/09/2005' 6

Algo así:

UPDATE PRUEBAS SET nContador = nRow() //suponiendo que nRow() fuera una
función que devuelva un número consecutivo..

Saludos,
José Luis Capel



Respuesta Responder a este mensaje
#4 Javier Loria
22/03/2007 - 06:25 | Informe spam
Hola:
Este tipo de sintaxis funciona de maravilla si son pocas filas pero debe
manejarse con mucho cuidado porque rápidamente deterioran el desempeño. El
siguiente código, que esta basado en AdventureWorks, muestra el problema:
= Crea Borrame
SET STATISTICS IO OFF;
SET NOCOUNT ON;
SELECT TOP 0 SalesOrderID, 1*SalesOrderDetailID AS SalesOrderDetailID
, CarrierTrackingNumber, OrderQty, ProductID, SpecialOfferID
, UnitPrice, UnitPriceDiscount, LineTotal, rowguid, ModifiedDate
INTO Borrame
FROM Sales.SalesOrderDetail

INSERT Borrame
SELECT TOP 1000 *
FROM Sales.SalesOrderDetail

PRINT '1000 Filas'
SET STATISTICS IO ON;
UPDATE Borrame
SET SalesOrderDetailID = (SELECT COUNT(*)
FROM Borrame t2
WHERE t2.SalesOrderID<=Borrame.SalesOrderID
OR (t2.SalesOrderID=Borrame.SalesOrderID
AND t2.ProductID<=Borrame.ProductID))
SET STATISTICS IO OFF;

DELETE Borrame
INSERT Borrame
SELECT TOP 2000 *
FROM Sales.SalesOrderDetail

PRINT '2000 Filas'
SET STATISTICS IO ON;
UPDATE Borrame
SET SalesOrderDetailID = (SELECT COUNT(*)
FROM Borrame t2
WHERE t2.SalesOrderID<=Borrame.SalesOrderID
OR (t2.SalesOrderID=Borrame.SalesOrderID
AND t2.ProductID<=Borrame.ProductID))

SET STATISTICS IO OFF;

DELETE Borrame
INSERT Borrame
SELECT TOP 3000 *
FROM Sales.SalesOrderDetail

PRINT '3000 Filas'
SET STATISTICS IO ON;
UPDATE Borrame
SET SalesOrderDetailID = (SELECT COUNT(*)
FROM Borrame t2
WHERE t2.SalesOrderID<=Borrame.SalesOrderID
OR (t2.SalesOrderID=Borrame.SalesOrderID
AND t2.ProductID<=Borrame.ProductID))
SET STATISTICS IO OFF;

DELETE Borrame
INSERT Borrame
SELECT TOP 4000 *
FROM Sales.SalesOrderDetail

PRINT '4000 Filas'
SET STATISTICS IO ON;
UPDATE Borrame
SET SalesOrderDetailID = (SELECT COUNT(*)
FROM Borrame t2
WHERE t2.SalesOrderID<=Borrame.SalesOrderID
OR (t2.SalesOrderID=Borrame.SalesOrderID
AND t2.ProductID<=Borrame.ProductID))
SET STATISTICS IO OFF;

DELETE Borrame
INSERT Borrame
SELECT TOP 5000 *
FROM Sales.SalesOrderDetail

PRINT '5000 Filas'
SET STATISTICS IO ON;

UPDATE Borrame
SET SalesOrderDetailID = (SELECT COUNT(*)
FROM Borrame t2
WHERE t2.SalesOrderID<=Borrame.SalesOrderID
OR (t2.SalesOrderID=Borrame.SalesOrderID
AND t2.ProductID<=Borrame.ProductID))
SET STATISTICS IO OFF;
DROP TABLE Borrame
= Los resultados son:
1000 Filas
Table 'Borrame'. Scan count 2, logical reads 1028 ...
Table 'Worktable'. Scan count 2, logical reads 9047 ...
2000 Filas
Table 'Borrame'. Scan count 2, logical reads 2068 ...
Table 'Worktable'. Scan count 2, logical reads 24100 ...
3000 Filas
Table 'Borrame'. Scan count 2, logical reads 3090 ...
Table 'Worktable'. Scan count 2, logical reads 45145 ...
4000 Filas
Table 'Borrame'. Scan count 2, logical reads 4124 ...
Table 'Worktable'. Scan count 2, logical reads 72198 ...
5000 Filas
Table 'Borrame'. Scan count 2, logical reads 5144 ...
Table 'Worktable'. Scan count 2, logical reads 105243 ...
La tabla Borrame no es problema ya que la lectura de paginas es claramente
lineal, pero el Worktable es casi exponencial lo que significa que para unas
15,000 a 25,000 filas es totalmente imposible de manejar, incluso con muy
buen hardware.
Un análisis del plan de mantenimiento mostrara un nested loop, que en
significa que se hace un ciclo que ejecuta el select interno para para cada
fila externa. O sea un para el caso de las 5000 filas, se convierte en un
5001 Selects, uno externo y 5000 internos. Esto no necesariamente siempre es
malo, pero en este caso si lo es porque para la primera fila externa solo se
requerira leer y sumar la primera fila, pero para la segunda fila externa se
requeriran 2, y asi sucesivamente. O sea al final se leeran 1+2+3+...+5000
filas o sea n! filas. :(
Saludos,


Javier Loria
Costa Rica (MVP)
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

"Rubén Vigón" wrote in message
news:
Hola José Luis,

Pueses hacerlo con una pequeña subconsulta de tipo COUNT(*); prueba lo
siguiente:

UPDATE TuTabla SET nContador = (SELECT COUNT(*) FROM TuTabla t2 WHERE
t2.nContador <= TuTabla.nContador)
_______________________________________

cCodigo dFecha nContador
0012 2005-09-01 00:00:00 1
0013 2005-09-02 00:00:00 2
0014 2005-09-01 00:00:00 3
0015 2005-09-03 00:00:00 4
0011 2005-09-04 00:00:00 5
0010 2005-09-05 00:00:00 6

(6 filas afectadas)
_______________________________________

Un saludo!

Rubén Vigón
Microsoft MVP Visual Basic
http://vigon.mvps.org
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida