Últimos artículos
Estas son las últimas entradas en el blog.
De todo un poco para solucionar los problemas diarios de un administrador de IT y DBA
Estas son las últimas entradas en el blog.
De todo un poco para solucionar los problemas diarios de un administrador de IT y DBA
Hoy veremos una manera simple de realizar un respaldo de todas nuestras bases de datos mediante un pequeño script.
-------------------------------------------------- --Variables DECLARE @Base_Datos VARCHAR(50) -- Nombre de la Base de Datos DECLARE @Ruta_Archivos VARCHAR(256) -- Ruta para los archivos DECLARE @Nombre_A VARCHAR(256) -- Nombre del Backup (1era Parte) DECLARE @Nombre_B VARCHAR(20) -- Nombre del Backup (2da Parte) -- 1-Ubicación de los backups SET @Ruta_Archivos = 'C:\Temp\' -- Nombre del Archivo (2da Parte) _YYYYMMDD SELECT @Nombre_B = (SELECT '_'+CONVERT(VARCHAR(20),GETDATE(),112) +'.BAK') DECLARE Cursor_Backup CURSOR READ_ONLY FOR SELECT name FROM master.dbo.sysdatabases WHERE name NOT IN ('master','model','msdb','tempdb') -- exclude these databases OPEN Cursor_Backup FETCH NEXT FROM Cursor_Backup INTO @Base_Datos WHILE @@FETCH_STATUS = 0 BEGIN SET @Nombre_A = @Ruta_Archivos + @Base_Datos + @Nombre_B BACKUP DATABASE @Base_Datos TO DISK = @Nombre_A FETCH NEXT FROM Cursor_Backup INTO @Base_Datos END CLOSE Cursor_Backup DEALLOCATE Cursor_Backup
Se puede optimizar el script para agregar nuevas opciones de backups, como así también programar el mismo.
Navegando por la web me tope con esta conjunto de scripts recomendado por Microsoft que aseguran ser útil para cualquier DBA
https://gallery.technet.microsoft.com/Some-random-collection-of-b607bf1b
Como siempre son para MS SQL Server.
Entre ellos encontré uno muy útil que analiza las estadísticas de una base en producción y trate de generarte el TSQL para crear los índices recomendados faltantes
/********************************************** --Missing Index Script **********************************************/ SELECT TOP 25 dm_mid.database_id AS DatabaseID, dm_migs.avg_user_impact*(dm_migs.user_seeks+dm_migs.user_scans) Avg_Estimated_Impact, dm_migs.last_user_seek AS Last_User_Seek, OBJECT_NAME(dm_mid.OBJECT_ID,dm_mid.database_id) AS [TableName], 'CREATE INDEX [IX_' + OBJECT_NAME(dm_mid.OBJECT_ID,dm_mid.database_id) + '_' + REPLACE(REPLACE(REPLACE(ISNULL(dm_mid.equality_columns,''),', ','_'),'[',''),']','') + CASE WHEN dm_mid.equality_columns IS NOT NULL AND dm_mid.inequality_columns IS NOT NULL THEN '_' ELSE '' END + REPLACE(REPLACE(REPLACE(ISNULL(dm_mid.inequality_columns,''),', ','_'),'[',''),']','') + ']' + ' ON ' + dm_mid.statement + ' (' + ISNULL (dm_mid.equality_columns,'') + CASE WHEN dm_mid.equality_columns IS NOT NULL AND dm_mid.inequality_columns IS NOT NULL THEN ',' ELSE '' END + ISNULL (dm_mid.inequality_columns, '') + ')' + ISNULL (' INCLUDE (' + dm_mid.included_columns + ')', '') AS Create_Statement FROM sys.dm_db_missing_index_groups dm_mig INNER JOIN sys.dm_db_missing_index_group_stats dm_migs ON dm_migs.group_handle = dm_mig.index_group_handle INNER JOIN sys.dm_db_missing_index_details dm_mid ON dm_mig.index_handle = dm_mid.index_handle WHERE dm_mid.database_ID = DB_ID() ORDER BY Avg_Estimated_Impact DESC GO
Luego de unos segundos veremos algo de este estilo:
Podremos ver el tiempo promedio estimado de mejora al realizar el índice, como el TSQL para crearlo.
(*) Un error que tiene el script es el nombre del índice que genera, que no debe superar los 128 caracteres, y en el mismo no lo contempla.
Por lo demás promete cumplir lo que ofrece….
Actualmente lo estoy probando en mis bases de producción como alternativa a la herramienta de análisis de rendimiento de MS SQL Server
Anteriormente habíamos visto como podíamos obtener:
Primer y último día de Mes Anterior, Actual y Siguiente.
Si te interesa ( y trabajas con una versión anterior a MS SQL Server 2012), les dejo el tutorial anterior:
https://maurobernal.com.ar/blog/t-sql/primer-y-ultimo-dia-del-mes-con-sql-server-y-otros/
Pero en esta oportunidad veremos otra variante para obtener el último día del mes: actual, mes anterior y mes siguiente.
A partir de Microsoft SQL Server 2012 se agregó la función EOMONTH()
https://docs.microsoft.com/en-us/sql/t-sql/functions/eomonth-transact-sql
La misma permite obtener el último día del mes
--GetDate() -> 14 Nov 2017 --Último día del mes Actual select EOMONTH(getdate()) as UltDiaMesActual --Último día del mes Anterior select EOMONTH(getdate(),-1) as UltDiaMesAnterior --Último día del mes Próximo select EOMONTH(getdate(),1) as UltDiaMesProximo
Esto nos dará como resultado:
A partir del código anterior, con un poco de ingenio, y con ayuda de la función DateAdd()
https://docs.microsoft.com/en-us/sql/t-sql/functions/dateadd-transact-sql
Si le agregamos un día podemos obtener el primer día del mes anterior, mes actual y mes próximo
--GetDate() -> 14 Nov 2017 --Primer día del Mes Anterior select dateadd(d,1,EOMONTH(getdate(),-2)) as PrimerDiaMesAnterior --Primer día del Mes Actual select dateadd(d,1,EOMONTH(getdate(),-1)) as PrimerDiaMesActual --Primer Dia del Mes Siguiente select dateadd(d,1,EOMONTH(getdate())) as PrimerDiaMesSiguiente
El resultado sería el siguiente:
No se olviden de comentar si les sirvió, !!! Y cualquier cosa que necesiten hacer es posible con un poco de paciencia…
Vamos primero con la documentación de estas dos funciones:
Rank:
https://docs.microsoft.com/en-us/sql/t-sql/functions/rank-transact-sql
Dense_Rank
https://docs.microsoft.com/en-us/sql/t-sql/functions/dense-rank-transact-sql
Primero crearemos un pequeña base de datos, que incluye un listado de vendedores, con sus ventas
IF EXISTS(SELECT 1 FROM sys.tables WHERE object_id = OBJECT_ID('myTable')) BEGIN; DROP TABLE [myTable]; END; GO CREATE TABLE [myTable] ( [myTableID] INTEGER NOT NULL IDENTITY(1, 1), [Vendedor] VARCHAR(255) NULL, [Ventas] VARCHAR(100) NULL, PRIMARY KEY ([myTableID]) ); GO INSERT INTO myTable([Vendedor],[Ventas]) VALUES('Bowen','$1.60'),('Becker','$31.71'),('Stanton','$95.81'),('Weaver','$60.26'),('Park','$65.37'),('Cook','$80.55'),('Pruitt','$60.42'),('Roberson','$20.23'),('Gilbert','$81.98'),('Emerson','$44.32'); INSERT INTO myTable([Vendedor],[Ventas]) VALUES('Harper','$1.60'),('Patrick','$98.08'),('Andrews','$35.71'),('Steele','$92.19'),('Moody','$1.90'),('Strong','$68.97'),('Rowland','$23.67'),('Barron','$79.18'),('Schultz','$80.94'),('Andrews','$1.92'); INSERT INTO myTable([Vendedor],[Ventas]) VALUES('Cleveland','$58.03'),('Head','$46.60'),('Hickman','$25.67'),('Cooke','$7.19'),('Farrell','$25.46'),('Sutton','$29.80'),('Dominguez','$85.95'),('Meadows','$70.26'),('Horne','$32.67'),('Cantu','$49.44'); INSERT INTO myTable([Vendedor],[Ventas]) VALUES('Mosley','$95.29'),('Gomez','$8.53'),('Noble','$81.25'),('Shaw','$47.67'),('Harper','$23.01'),('Reese','$2.46'),('Brown','$36.73'),('Hardin','$0.65'),('Marshall','$7.98'),('Combs','$60.59'); INSERT INTO myTable([Vendedor],[Ventas]) VALUES('Hicks','$2.78'),('Cote','$15.58'),('Knight','$91.91'),('Gilliam','$75.10'),('Leblanc','$11.16'),('Franklin','$13.92'),('Powers','$1.45'),('Clark','$36.26'),('Rose','$22.70'),('Hoover','$78.61'); INSERT INTO myTable([Vendedor],[Ventas]) VALUES('Hines','$45.97'),('Lowery','$29.76'),('Le','$63.35'),('Allison','$96.55'),('Fulton','$34.28'),('Cleveland','$46.02'),('Brewer','$1.60'),('Howe','$1.60'),('Sims','$26.47'),('Fox','$55.71'); INSERT INTO myTable([Vendedor],[Ventas]) VALUES('Bentley','$28.30'),('Hahn','$81.10'),('Colon','$62.66'),('Le','$3.42'),('House','$90.24'),('Kemp','$93.13'),('Cooper','$85.59'),('Mosley','$46.40'),('Jacobs','$1.58'),('Dickson','$76.56'); INSERT INTO myTable([Vendedor],[Ventas]) VALUES('Jacobs','$46.47'),('Moon','$77.90'),('Palmer','$52.45'),('Bray','$99.29'),('Franco','$50.64'),('Erickson','$21.77'),('Joyce','$32.19'),('Kline','$4.15'),('Barrera','$71.70'),('Jacobs','$58.56'); INSERT INTO myTable([Vendedor],[Ventas]) VALUES('Mercer','$95.18'),('Horn','$43.12'),('Mendoza','$42.59'),('Mays','$59.19'),('Shaw','$33.63'),('Sawyer','$58.80'),('Chen','$43.88'),('Dorsey','$32.79'),('Howard','$50.02'),('Marshall','$81.84'); INSERT INTO myTable([Vendedor],[Ventas]) VALUES('Casey','$2.67'),('Boyer','$39.07'),('Richards','$31.92'),('Larson','$64.99'),('Drake','$42.46'),('Holmes','$28.37'),('Hicks','$21.46'),('Richardson','$89.33'),('Evans','$8.90'),('Crawford','$11.28');
Esta tabla desordenada contiene el listado de vendedores, con sus respectivas Ventas
select * from myTable
La idea de estas dos funciones es armar un ranking.
Semejanza: Ambas, en el caso de que empaten le ponen el mismo número de ranking
Diferencia: Al caso siguiente luego del empate Rank no le pone el inmediato superior, si no que mantiene la cuenta de la cantidad de elementos que lleva hasta el momento y le pone el siguiente. A diferencia de Dense_Rank que continúa con el siguiente correlativo al del empate
Con Rank
select *, RANK() over (Order by Ventas) as Ranking from myTable
Con Dense_Rank
select *, DENSE_RANK() over ( Order by Ventas) as Ranking from myTable
ts
Hoy vamos usar row_number(), una subconsulta, comando IN para buscar y eliminar registros repetidos.
En esta nueva etapa me he propuesto compartir cada uno de los scripts que siempre son de utilidad cuando se trabaja con bases de datos.
Como siempre son con TSQL para MS SQL Server.
Esta vez veremos como eliminar registros repetidos de una tabla, solo dejando 1 registro.
El secreto está en el uso del comando ROW_NUMBER
https://docs.microsoft.com/en-us/sql/t-sql/functions/row-number-transact-sql
IF EXISTS(SELECT 1 FROM sys.tables WHERE object_id = OBJECT_ID('myTable')) BEGIN; DROP TABLE [myTable]; END; GO CREATE TABLE [myTable] ( [myTableID] INTEGER NOT NULL IDENTITY(1, 1), [Documento] VARCHAR(13) NULL, [Nombre] VARCHAR(255) NULL, PRIMARY KEY ([myTableID]) ); GO INSERT INTO myTable([Documento],[Nombre]) VALUES('1695071197799','Jin'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1630121141299','Harlan'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1637061077799','Armand'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1653081722499','Chadwick'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1695020909099','Fletcher'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1614102485499','Garth'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1624071487999','Cedric'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1678010341799','Prescott'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1695071197799','Jin'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1630121141299','Harlan'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1637061077799','Armand'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1653081722499','Chadwick'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1691081716399','Harding'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1641101376799','Jakeem'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1630020717199','Carlos'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1627101503999','Edan'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1636051993199','Samson'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1627041338699','Wylie'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1661032884599','Brennan'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1625120186899','Brett'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1642100764499','Ira'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1624052909599','Kyle'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1656062403199','Jordan'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1656041722899','Keane'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1630122181399','Cain'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1634062813199','Stone'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1615111655399','Elton'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1609092165099','Theodore'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1682111461299','Noble'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1656041722899','Keane'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1630122181399','Cain'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1634062813199','Stone'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1615111655399','Elton'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1609092165099','Theodore'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1682111461299','Noble'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1656041722899','Keane'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1630122181399','Cain'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1634062813199','Stone'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1615111655399','Elton'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1609092165099','Theodore'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1682111461299','Noble'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1656020101399','Alden'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1657080142799','Tanek'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1678122145299','Fulton'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1684010635799','Reese'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1613011065899','Grant'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1630012756499','Jakeem'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1618071462499','Flynn'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1615052518299','Benjamin'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1691052832399','Wylie'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1669013054199','Tucker'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1612110409199','Laith'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1614110752199','Tad'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1699041337299','Chaney'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1650112954899','Jeremy'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1647052552299','Adam'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1643041374799','Denton'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1642081947099','Knox'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1643020793199','Vance'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1632020546699','Thaddeus'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1670032188999','Keegan'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1615102660699','Clark'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1693053059399','Hedley'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1661082842999','Beau'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1636081862699','August'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1608070833799','Oscar'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1687121074299','Leo'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1655122056599','Griffith'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1614010191199','Andrew'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1668121357799','Abdul'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1691081716399','Harding'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1641101376799','Jakeem'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1630020717199','Carlos'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1627101503999','Edan'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1636051993199','Samson'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1627041338699','Wylie'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1661032884599','Brennan'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1625120186899','Brett'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1642100764499','Ira'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1602091000299','Jordan'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1602060613699','Guy'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1656041722899','Keane'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1630122181399','Cain'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1634062813199','Stone'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1615111655399','Elton'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1609092165099','Theodore'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1682111461299','Noble'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1649101947099','Bradley'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1692080607499','Basil'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1645013071199','Bruce'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1677121204299','Chancellor'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1668110667099','Price'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1644072576599','Driscoll'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1616101911399','August'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1680021349199','Wallace'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1652052495999','Emery'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1692050724999','Talon'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1614111114799','Avram'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1670010342799','Hiram'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1636022785999','Brody'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1609033047099','Stuart'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1669122235799','Moses'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1626080826599','Leo'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1670010510999','Micah'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1676043021599','Jonah'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1621032365499','Len'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1658020481699','Amir'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1611032912899','Len'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1638071718599','Ray'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1676120168199','Kenyon'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1688050847099','Sawyer'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1692051561099','Malcolm'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1664101012499','Nolan'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1682121754399','Lucius'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1633112425699','Alvin'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1606040846399','Ralph'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1610061348699','Jin'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1649120964999','Malachi'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1609121778799','Kermit'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1649111157999','Wade'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1625051934199','Simon'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1698060420799','Donovan'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1607101359699','Isaiah'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1648100677099','Avram'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1668081567999','Grant'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1613042285999','Keefe'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1626042455399','Joshua'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1676081014999','Amir'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1643042339599','Conan'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1695051340499','Jin'); INSERT INTO myTable([Documento],[Nombre]) VALUES('1610012015699','Akeem');
Esta pequeña tabla de ejemplo tiene la siguiente estructura:
Lo primero que haremos es buscar los que tienen el campo DOCUMENTO repetido usando la función Row_Number(). Esta nos devolverá un nuevo campo que llamaremos ORDEN, e indicara las veces que se repite un campo
select *,ROW_NUMBER() over ( PARTITION BY Documento ORDER BY myTableID) as Orden from mytable
PARTITION BY Documento le indicamos que la partición sea el campo documento
ORDER BY myTableID le indicamos el criterio para enumerar. Es decir en orden ascendente por ID del campo. Si tuviésemos un campo de tipo fecha (Datetime) podríamos ordenar por mas nuevo, o viceversa
Lo primero que haremos es buscar los repetidos usando una subconsulta
Select myTableID from (select *,ROW_NUMBER() over ( PARTITION BY Documento ORDER BY myTableID) as Orden from mytable) SubConsulta1 where Orden>1
Esta consulta devuelve los ID de los repetidos: 31 registros para ser mas especificos
Ahora los eliminamos usando el comando IN
begin transaction eliminacion1 delete from mytable where mytableID in ( Select myTableID from (select *,ROW_NUMBER() over ( PARTITION BY Documento ORDER BY myTableID) as Orden from mytable) SubConsulta1 where Orden>1 ) commit transaction eliminacion1
Espero que les haya sido útil.
El comando Row_Number() permite trabajar con los registros de forma masiva pudiendo identificar la N aparición.
Mas adelante veremos como eliminar / actualizar:
-El último registro de una serie de registros
-El primero, etc…
Siguiendo con estas funciones de TSQL para MS SQL Server, en esta ocasión es para validar los 22 dígitos del CBU.
La Clave Bancaria Uniforme (CBU) se compone de 22 dígitos
https://es.wikipedia.org/wiki/Clave_Bancaria_Uniforme
CREATE FUNCTION [dbo].[ValidarCBUdigito] ( -- Add the parameters for the function here @block VARCHAR(100) ) RETURNS TINYINT AS BEGIN DECLARE @subblock VARCHAR(100) DECLARE @posicion INTEGER DECLARE @digito CHAR(1) DECLARE @Pond CHAR(4) DECLARE @largo INTEGER DECLARE @suma INTEGER SELECT @suma = 0 SELECT @largo = LEN ( @block ) SELECT @digito = SUBSTRING ( @block , @largo , 1 ) SELECT @subblock = SUBSTRING ( @block , 1 , @largo - 1 ) SELECT @Pond = '9713' SELECT @posicion = 1 WHILE @posicion <= @largo - 1 BEGIN SELECT @suma = @suma + CONVERT( INTEGER , SUBSTRING ( @subblock , @largo - @posicion , 1 )) * CONVERT( INTEGER , SUBSTRING ( @pond ,CASE (@posicion % 4) WHEN 1 THEN 4 WHEN 2 THEN 3 WHEN 3 THEN 2 WHEN 0 THEN 1 END , 1 ) ) SELECT @posicion = @posicion + 1 END if @digito = RIGHT ( convert( varchar, 10 - ( @suma % 10 )) , 1 ) RETURN 1 RETURN 0 END
IT CallCenters
Desarrollo de aplicaciones web y mobile