Categorías
Donaciones

Todo el contenido es gratuito y en beneficio de la comunidad. Puedes reconocer el esfuerzo con una donación si lo deseas.

Inserte aquí su publicidad

Hoy surgió esta necesidad. Trabajando en un conjunto de funciones de búsqueda difusa, pero así online (no en modo batch, para eso ya tenemos DQS), vimos que la forma en la que están implementados los algoritmos típicos, como Jaro-Winkler o Jaccard, en las funciones de Master Data Service era especialmente eficiente. Así, haciendo uso de la función “mdq.Similarity” se obtiene una búsqueda para usar en un procedimiento almacenado con un resultado bastante apañado. El problemilla estaba en querer usarlo en una instancia sin MDS instalado, ni ganas de instalarlo, ya que siendo SQL Server 2008 R2, aun siendo factible, no es especialmente fácil de mantener.

Empleamos la vía rápida. Tomar un script del assembly (de los de botón derecho + create script) y de la función de una instancia 2012 y crearlo en la instancia 2008 R2, y hete aquí que funciona. ¿Soportado? No creo. ¿Buena idea? No lo sé aún. Pero el caso es que funciona y, bueno, habrá que probar a ver cómo va.

CREATE ASSEMBLY [Microsoft.MasterDataServices.DataQuality]
FROM 0x4D5A90000300000004000000FFF ....--> lo corto por razones estéticas
WITH PERMISSION_SET = SAFE

GO

--Cambiar el esquema de "mdq" a otro
CREATE FUNCTION [dbo].[Similarity](@input1 [nvarchar](4000), @input2 [nvarchar](4000), @method [tinyint], @containmentBias [float], @minScoreHint [float])
RETURNS [float] WITH EXECUTE AS CALLER, RETURNS NULL ON NULL INPUT
AS 
EXTERNAL NAME [Microsoft.MasterDataServices.DataQuality].[Microsoft.MasterDataServices.DataQuality.SqlClr].[Similarity]

GO

Un link con más info sobre estas funciones de búsqueda difusa en MDS: http://sqlblog.com/blogs/jamie_thomson/archive/2009/11/09/fuzzy-logic-and-regex-come-to-t-sql-in-sql-server-2008-r2-available-now.aspx

Los amigos de ApexSQL contactaron conmigo hace unas semanas para recordarme que por ser MVP, me regalaban una licencia de sus productos (o como dicen ellos, “Your money is no good here“). Quedé gratamente sorprendido, porque no es algo corriente que llamen a tu puerta para darte algo gratis y sin compromiso. Lo menos que podía hacer es utilizar las herramientas y hablar de ellas, de forma que pudiera compensar mínimamente esa deferencia que estaban teniendo conmigo.

No había tenido la oportunidad de probar el software de ApexSQL, aunque sí que había oído hablar de él. Después de contar con el producto instalado, pasaron varias semanas antes de que pudiera tener un rato para probarlo. Y hete aquí que hace un par de días me vi en la tesitura de tener que hacer una comparación de esquemas entre dos bases de datos para la preparación de una subida a producción que mañana tendré que realizar (de las buenas, buenas, de esas de las que antes de empezar te haces dos backups). Ahí me acordé de ApexSQL Diff, ya que sin haberlo usado, sabía que estaba ahí, ya que integra el acceso a los distintos programas en Management Studio, tanto en el menú principal como en numerosos puntos del árbol:

ApexSQL Diff 1

ApexSQL Diff 1

ApexSQL Diff 2

ApexSQL Diff 2

Y una vez en la herramienta, (depende de cómo accedas, la primera pantalla será de Management Studio o de ApexSQL Diff, en la que eliges base de datos de origen y base de datos de destino) el punto de entrada la impresión es similar a otros aplicativos de similares características, lo que hace que no tengas que dedicarle ni dos minutos a aprender a utilizarlo.

El siguiente punto es para mí el que más me ha llamado la atención, y es que la comparación la realiza notablemente más rápido que otras utilidades similares. De hecho, la primera vez pensé que no había funcionado bien alguna cosa. Incluso con bases de datos grandes, de varios miles de objetos, presenta la vista de diferencias en un tiempo reducido.

ApexSQL Diff 3

ApexSQL Diff 3

ApexSQL Diff 4

ApexSQL Diff 4

La selección de objetos a comparar y las cosas que uno quiere que se comparen es ágil y nada pesada de configurar, con las cosas obvias ya marcadas por cierto, pero con la gama completa de posibilidades (lo que está, lo que no, lo diferente, agrupado por tipo de objeto, posibilidad de desmarcar o marcar cualquier tipo de aspecto). Rápidamente se pasa a la fase de sincronización, que es una especie de asistente en el que te elabora una lista de dependencias (que puedes incorporar o no, según convenga) y un paso de advertencias en el que te notifica a qué te expones con lo que se va a realizar. Finalmente llegas al punto en el que eliges entre sincronizar o generar un script que lo haga, punto en el que sabiamente se te ofrece por defecto lo segundo, y dentro de ello hasta te da opciones de abrir Management Studio directamente, generar el fichero y varias opciones más:

ApexSQL Diff 5

Esto es así a primera vista. Luego cuenta con otro montón de características como la posibilidad de salvar una comparativa (y esto es muy útil si has estado configurando y seleccionando un subconjunto de objetos a comparar) o exportarla a varios formatos.

En definitiva, es todo un hallazgo. Espero poder tener tiempo para probar otras herramientas de ApexSQL, tienen un montón, muchas de ellas gratuitas, que desde aquí os invito a probar.

Las CTEs sirven para muchas cosas, también para calcular el solsticio de invierno en el hemisferio norte:

;With CTE as (
Select Dia, D = row_number() over (order by datediff(ss, Hora_Alba, Hora_Ocaso))
From Calendario_Solar --> Obtener de http://aa.usno.navy.mil/data/docs/RS_OneYear.php
Where Año=2013
)
Select 
  Navidad = dateadd(dd, 4, Dia)
From CTE
Where D = 1

 

Luego, esta fecha y sus proximidades es celebrada muchas culturas de diversas formas y con diversos nombres. En una de esas culturas, se desea Feliz Navidad.

Ya viene SQL Server 2014, lo que significa por lo menos que hay que ponerse a leer para ir aprendiendo. Y eso he hecho, por lo menos de la estrella revolucionaria que esta versión traerá debajo del brazo, in-memory OLTP. Después de unos cuantos whitepapers, guías, blogs, etc., recojo aquí un conjunto de preguntas que yo mismo me he hecho y a las que a algunas le he ido encontrando respuesta de cara a suavizar el golpe a los que comiencen. Lo haré en dos partes, esta primera más del lado técnica (aunque sin profundizar en lo teórico para no perderse), y una segunda más filosófica o reflexiva sobre le cambio. Vayamos a ello.

Hekaton

Nombre en clave de la funcionalidad in-memory OLTP, la estrella en SQL Server 2014. También llamado XTP (extreme transaction processing).

¿Qué es?

La explicación corta, los datos residen permanentemente en memoria, no en disco, con lo que al trabajar siempre en caché, se suprimen a la vez las esperas por disco y las esperas por bloqueos, lo que aumenta dramáticamente el rendimiento.

¿Por qué surge?

El disco es lo más lento de un sistema de bases de datos. El SSD es carísimo. La CPU hace ya bastante que no corre más, de hecho, el escalado va por multiplicar los núcleos y procesadores de un servidor, pero una consulta simple no corre en más de un core. Sin embargo, la memoria es muy barata, al ser casi un consumible de cliente, y puedes montar un servidor con 2 Tb de RAM sin que el coste sea astronómico. La solución pasa por tenerlo todo en memoria.

(Bueno, también surge porque motores de la competencia lo tienen, véase SAP Hana u Oracle Exadata.)

¿Si los datos no están en el disco, dónde están cuando se para el servicio?

Existe un trabajo en background que va salvando a disco los datos cambiados y borrados (aparte, una especie de checkpoint continuo en la sombra para que cuando se pare el servidor, los datos no se pierdan). Se estructuran bloques de 128 Mb y se van realizando las lecturas del log de transacciones para poder hacer el redo o recovery. De hecho, hay dos, el “data” y el “delta” (el delta es en el que se anotan los registros borrados). Cuando se inicia el servicio, como parte del redo o recovery, se suben a memoria los datos (data), todos, salvo los borrados (delta). Examinando el “fichero”, se observa que es un directorio con un buen montón de ficheros, entre los que hay un conjunto de ellos de 128Mb de tamaño.

¿Cómo es que no hay bloqueos?

No hay ningún tipo de bloqueo, se gestionan por snapshot (por defecto) y se controla por timestamp cuál es el valor válido del registro. Al iniciar una actualización, tomas tu versión del registro, lo cambias y se marca, se guardo lo que había y lo nuevo y se diferencia el “estado actual” de la tabla por el timestamp.

¿Cómo se estructuran las páginas en esa memoria?

No, ya no hay páginas. La estructura es totalmente diferente. Son acumulaciones de información de registros en un hash (no en arbol B) en los que en cada registro tiene acoplada la ordenación de cada índice definido para la tabla. De hecho, los registros de una misma tabla no tienen ni por qué estar cerca.

¿Todas las tablas tienen que estar en memoria en una base de datos?

No, no es necesario, puede haber tablas que estén en memoria y tablas que no. Eso sí, hay que marcar la base de datos para que permita la posibilidad de crear tablas in-memory.

¿Cómo es el acceso a los datos?

El T-SQL es el mismo, existe dentro del motor un intérprete que transforma el código a sintaxis para acceder a tablas en memoria. También se pueden construir consultas que mezclen unas tablas en memoria y otras en disco. Sin embargo, para el acceso exclusivo a tablas en memoria, lo ideal es preparar procedimientos almacenados compilados en forma nativa (concepto nuevo también). Hay algunas cosillas raras en la creación de tablas y de estos procedimientos almacenados, pero nada especialmente complicado.

¿Native Compiled Stored Procedures?

La gran ventaja de estos Native Compiled SPs está en que ahorras capas de llamadas a funciones que componen cada operador de un plan de ejecución, puntos intermedios que al final suponen consumo de CPU a la hora de ejecutar un plan de ejecución ya compilado. Estos procedimientos compilados de forma nativa ya van en C, dentro de una DLL que se carga en el sqlsvr.exe, todo está ya dentro. Ojo, esto tiene unas connotaciones importantes para el rendimiento que hay que tener en cuenta, no todo son cosas buenas. Sólo valen para casos en los que todas las tablas implicadas residan en memoria.

¿Vale todo? ¿Qué no se puede hacer?

Hay bastantes, las que son más significativas para mí son:

  • No se pueden usar tipos de datos grandes, estando cada registro está limitado a 8000 bytes potenciales. Ni varchar(max) ni ningún otro blob de los que siguen estando en esta versión.
  • No se pueden modificar las tablas con un ALTER (hay que borrar y volver a crear). Y los índices se crean con la tabla, no se pueden crear después. Tampoco se pueden truncar tablas.
  • La intercalación también está muy restringida (sólo de Windows, _BIN2 para campos que estén indexados).
  • Tampoco puede hacerse una consulta a dos tablas que estén en distintas bases de datos (ni un inner join ni un inser..select).
  • No todas las funciones están admitidas, aunque sí la mayoría.
  • Tampoco se pueden crear cursores (evitando así el oxímoron).
  • No se pueden usar identities (hay que usar secuencias).

¿Se puede pasar una tabla en disco a tabla en memoria?

Sí, eso facilita mucho las migraciones. Aunque hay que hacer notables adaptaciones en las aplicaciones.

¿Y para el ETL?

Pues también, sobre todo para cuando se tienen que guardar tablas de staging. Hay una funcionalidad concreta que permite no tener que persistir nada, sólo se conserva la estructura (tipo tempdb, pero en memoria). Al no tener que escribir nada en disco, el rendimiento se dispara. Cuando le pasa algo al servicio, estas tablas se crean de nuevo vacías (algo que de todas formas ya se hace por el mero significado de ellas, son intermedias que se “truncan” y cargan en cada ejecución del proceso).

Conclusión

El resumen es que la idea no es en qué tablas y aplicaciones emplear Hekaton, sino en qué casos no podrá ser utilizado, ya que la diferencia potencial en rendimiento es la que hay entre la velocidad de un disco y la memoria. Hay que tener reservas y tener también muy claro que hay que cuidarse de querer solucionar problemas con esto, orientándolo más a desarrollos nuevos o a mejorar/escalar desarrollos existentes que ya afinados.

Preguntas del más allá (sin respuesta, algunas)

¿Por qué tras tanto empeño de MS (y el resto) en el cloud, ahora esta monstruosa funcionalidad orientada 100% al on-premisse?

Si se buscaba optimizar la escritura en OLTP, ¿por qué no va tempdb, donde se producen entorno al 50% de las escrituras, de forma nativa, dentro de memoria (y no va, al menos por ahora, con la de limitaciones que hay con la intercalación)?

¿Y no hay nada más que esto? Por supuesto que sí, aunque sin duda esta funcionalidad es la principal novedad.

Bibliografía

Algunos de los documentos y referencias consultadas, así como documentación para profundizar.

http://blogs.technet.com/b/dataplatforminsider/archive/2013/08/01/hardware-considerations-for-in-memory-oltp-in-sql-server-2014.aspx

http://en.wikipedia.org/wiki/Hekaton_(database)

http://download.microsoft.com/download/F/5/0/F5096A71-3C31-4E9F-864E-A6D097A64805/SQL_Server_Hekaton_CTP1_White_Paper.pdf

http://technet.microsoft.com/es-es/evalcenter/dn205290.aspx

http://msdn.microsoft.com/en-us/library/dn133186(v=sql.120).aspx

http://technet.microsoft.com/en-us/library/dn296374(v=sql.120).aspx

http://research.microsoft.com/pubs/193594/Hekaton%20-%20Sigmod2013%20final.pdf

http://blogs.msdn.com/b/arvindsh/archive/2013/07/03/sql-2014-in-memory-oltp-hekaton-training-videos-and-white-papers.aspx

A raíz de un post en el foro de SQL Server (link), en el que se preguntaba cómo realizar la tabla de clasificación de una competición deportiva con t-SQL, he preparado este mecanismo para llevarlo a cabo. No va mucho más allá de ser un pasatiempo, pero ha sido un pasatiempo divertido.

Se partía de una tabla, proporcionada por el usuario, con los resultados de la temporada de fútbol 2000-2001 de 1ª división de España. Para elaborar la clasificación, hacen falta unos criterios de ordenación en caso de empates, que están en la normativa del organismo que la organiza. En este caso era una dada por el propio usuario (ver el hilo en el foro). Se añaden unas tablas para obtener un modelo que sea más fácilmente explotable y que se carga partiendo de ese origen único, para finalmente preparar un procedimiento almacenado que actualiza la clasificación.

(

CREATE TABLE [dbo].[Resumen 2001][ID] [int] NOT NULL,
[TEMPORADA] [varchar](50) NULL,
[DIVISION] [int] NULL,
[JORNADA] [int] NULL,
[EQUIPO_LOCAL] [varchar](50) NULL,
[EQUIPO_VISITANTE] [varchar](50) NULL,
[GOLES_LOCAL] [int] NULL,
[GOLES_VISITANTE] [int] NULL,
CONSTRAINT [PK_Resumen 2001] PRIMARY KEY CLUSTERED
(
[ID] ASC
)
GO

--Tabla para los equipos
create table Equipos (
  IdEquipo tinyint not null primary key clustered identity (1,1),
  Nombre varchar(20) not null ,
  Pos_Juego_Limpio tinyint not null)
go
-- Tabla para guardar los partidos que cada equipo disputa
-- Cada partido figura dos veces, una vez por cada equipo que lo juega
create table Partidos_Equipo (
  IdPartido smallint not null,
  IdEquipo tinyint not null,
  IdEquipo_Contrario tinyint not null,
  Es_Local bit not null, 
  Goles_A_Favor tinyint not null,
  Goles_En_Contra tinyint not null,
  Puntos tinyint,
  primary key clustered (IdPartido, IdEquipo))
go
-- Tabla para persistir la clasificación
create table Clasificacion (
  IdEquipo tinyint not null primary key clustered,
  PJ tinyint not null,  --Partidos jugados
  PG tinyint not null, --Partidos ganados
  PE tinyint not null, --Partidos empatados
  PP tinyint not null, --Partidos perdidos
  GF tinyint not null, --Goles a favor,
  GC tinyint not null, --Goles en contra,
  DG smallint not null, --Diferencia de goles
  Puntos tinyint not null, --Puntos
  Desempate tinyint not null) --Desempate
go
--El campo desempate es el que permite que, a igualdad de puntos,
--haciendo uso de las reglas de la competición, se ubiquen los equipos

--Datos con los resultados
INSERT INTO [dbo].[Resumen 2001] VALUES  (1,'00/01',1,1,'Osasuna','Celta',0,2),
  (2,'00/01',1,1,'Zaragoza','Espanyol',1,2),
  (3,'00/01',1,1,'Villarreal','Rayo Vallecano',1,5),
  (4,'00/01',1,1,'Las Palmas','Alavés',0,3),
  (5,'00/01',1,1,'Numancia','Oviedo',1,0),
  (6,'00/01',1,1,'Mallorca','Valladolid',1,1),
  (7,'00/01',1,1,'Real Madrid','Valencia',2,1),
  (8,'00/01',1,1,'Barcelona','Málaga',2,1),
  (9,'00/01',1,1,'Dptivo. Coruña','Ath. Bilbao',2,0),
  (10,'00/01',1,1,'Real Sociedad','Rac. Santander',2,2),
  (11,'00/01',1,2,'Celta','Real Sociedad',4,1),
  (12,'00/01',1,2,'Espanyol','Osasuna',1,2),
  (13,'00/01',1,2,'Rayo Vallecano','Zaragoza',0,0),
  (14,'00/01',1,2,'Alavés','Villarreal',0,1),
  (15,'00/01',1,2,'Oviedo','Las Palmas',2,2),
  (16,'00/01',1,2,'Valladolid','Numancia',2,0),
  (17,'00/01',1,2,'Valencia','Mallorca',4,0),
  (18,'00/01',1,2,'Málaga','Real Madrid',3,3),
  (19,'00/01',1,2,'Ath. Bilbao','Barcelona',3,1),
  (20,'00/01',1,2,'Rac. Santander','Dptivo. Coruña',0,3),
  (21,'00/01',1,3,'Celta','Espanyol',1,0),
  (22,'00/01',1,3,'Osasuna','Rayo Vallecano',2,2),
  (23,'00/01',1,3,'Zaragoza','Alavés',2,2),
  (24,'00/01',1,3,'Villarreal','Oviedo',1,0),
  (25,'00/01',1,3,'Las Palmas','Valladolid',1,1),
  (26,'00/01',1,3,'Numancia','Valencia',0,3),
  (27,'00/01',1,3,'Mallorca','Málaga',0,1),
  (28,'00/01',1,3,'Real Madrid','Ath. Bilbao',4,1),
  (29,'00/01',1,3,'Barcelona','Rac. Santander',3,1),
  (30,'00/01',1,3,'Real Sociedad','Dptivo. Coruña',1,1),
  (31,'00/01',1,4,'Espanyol','Real Sociedad',1,2),
  (32,'00/01',1,4,'Rayo Vallecano','Celta',3,0),
  (33,'00/01',1,4,'Alavés','Osasuna',2,0),
  (34,'00/01',1,4,'Oviedo','Zaragoza',2,1),
  (35,'00/01',1,4,'Valladolid','Villarreal',0,0),
  (36,'00/01',1,4,'Valencia','Las Palmas',5,1),
  (37,'00/01',1,4,'Málaga','Numancia',1,3),
  (38,'00/01',1,4,'Ath. Bilbao','Mallorca',2,1),
  (39,'00/01',1,4,'Rac. Santander','Real Madrid',0,0),
  (40,'00/01',1,4,'Dptivo. Coruña','Barcelona',2,0),
  (41,'00/01',1,5,'Espanyol','Rayo Vallecano',0,0),
  (42,'00/01',1,5,'Celta','Alavés',1,1),
  (43,'00/01',1,5,'Osasuna','Oviedo',0,0),
  (44,'00/01',1,5,'Zaragoza','Valladolid',0,0),
  (45,'00/01',1,5,'Villarreal','Valencia',1,1),
  (46,'00/01',1,5,'Las Palmas','Málaga',2,1),
  (47,'00/01',1,5,'Numancia','Ath. Bilbao',0,0),
  (48,'00/01',1,5,'Mallorca','Rac. Santander',2,1),
  (49,'00/01',1,5,'Real Madrid','Dptivo. Coruña',3,0),
  (50,'00/01',1,5,'Real Sociedad','Barcelona',0,6),
  (51,'00/01',1,6,'Rayo Vallecano','Real Sociedad',4,1),
  (52,'00/01',1,6,'Alavés','Espanyol',1,0),
  (53,'00/01',1,6,'Oviedo','Celta',3,1),
  (54,'00/01',1,6,'Valladolid','Osasuna',1,1),
  (55,'00/01',1,6,'Valencia','Zaragoza',1,0),
  (56,'00/01',1,6,'Málaga','Villarreal',2,1),
  (57,'00/01',1,6,'Ath. Bilbao','Las Palmas',0,3),
  (58,'00/01',1,6,'Rac. Santander','Numancia',4,2),
  (59,'00/01',1,6,'Dptivo. Coruña','Mallorca',1,1),
  (60,'00/01',1,6,'Barcelona','Real Madrid',2,0),
  (61,'00/01',1,7,'Rayo Vallecano','Alavés',0,1),
  (62,'00/01',1,7,'Espanyol','Oviedo',2,0),
  (63,'00/01',1,7,'Celta','Valladolid',2,1),
  (64,'00/01',1,7,'Osasuna','Valencia',1,2),
  (65,'00/01',1,7,'Zaragoza','Málaga',1,1),
  (66,'00/01',1,7,'Villarreal','Ath. Bilbao',0,0),
  (67,'00/01',1,7,'Las Palmas','Rac. Santander',2,1),
  (68,'00/01',1,7,'Numancia','Dptivo. Coruña',1,2),
  (69,'00/01',1,7,'Mallorca','Barcelona',2,0),
  (70,'00/01',1,7,'Real Sociedad','Real Madrid',1,4),
  (71,'00/01',1,8,'Alavés','Real Sociedad',0,1),
  (72,'00/01',1,8,'Oviedo','Rayo Vallecano',4,1),
  (73,'00/01',1,8,'Valladolid','Espanyol',1,1),
  (74,'00/01',1,8,'Valencia','Celta',1,0),
  (75,'00/01',1,8,'Málaga','Osasuna',3,1),
  (76,'00/01',1,8,'Ath. Bilbao','Zaragoza',1,2),
  (77,'00/01',1,8,'Rac. Santander','Villarreal',3,1),
  (78,'00/01',1,8,'Dptivo. Coruña','Las Palmas',4,0),
  (79,'00/01',1,8,'Barcelona','Numancia',1,1),
  (80,'00/01',1,8,'Real Madrid','Mallorca',0,2),
  (81,'00/01',1,9,'Alavés','Oviedo',4,0),
  (82,'00/01',1,9,'Rayo Vallecano','Valladolid',2,1),
  (83,'00/01',1,9,'Espanyol','Valencia',1,0),
  (84,'00/01',1,9,'Celta','Málaga',1,0),
  (85,'00/01',1,9,'Osasuna','Ath. Bilbao',1,1),
  (86,'00/01',1,9,'Zaragoza','Rac. Santander',2,0),
  (87,'00/01',1,9,'Villarreal','Dptivo. Coruña',3,2),
  (88,'00/01',1,9,'Las Palmas','Barcelona',0,1),
  (89,'00/01',1,9,'Numancia','Real Madrid',3,1),
  (90,'00/01',1,9,'Real Sociedad','Mallorca',0,1),
  (91,'00/01',1,10,'Oviedo','Real Sociedad',1,0),
  (92,'00/01',1,10,'Valladolid','Alavés',2,1),
  (93,'00/01',1,10,'Valencia','Rayo Vallecano',2,2),
  (94,'00/01',1,10,'Málaga','Espanyol',0,0),
  (95,'00/01',1,10,'Ath. Bilbao','Celta',2,1),
  (96,'00/01',1,10,'Rac. Santander','Osasuna',0,0),
  (97,'00/01',1,10,'Dptivo. Coruña','Zaragoza',2,0),
  (98,'00/01',1,10,'Barcelona','Villarreal',1,2),
  (99,'00/01',1,10,'Real Madrid','Las Palmas',5,1),
  (100,'00/01',1,10,'Mallorca','Numancia',2,1),
  (101,'00/01',1,11,'Oviedo','Valladolid',4,1),
  (102,'00/01',1,11,'Alavés','Valencia',1,1),
  (103,'00/01',1,11,'Rayo Vallecano','Málaga',4,2),
  (104,'00/01',1,11,'Espanyol','Ath. Bilbao',2,1),
  (105,'00/01',1,11,'Celta','Rac. Santander',1,1),
  (106,'00/01',1,11,'Osasuna','Dptivo. Coruña',1,1),
  (107,'00/01',1,11,'Zaragoza','Barcelona',3,1),
  (108,'00/01',1,11,'Villarreal','Real Madrid',0,1),
  (109,'00/01',1,11,'Las Palmas','Mallorca',1,0),
  (110,'00/01',1,11,'Real Sociedad','Numancia',4,1),
  (111,'00/01',1,12,'Valladolid','Real Sociedad',2,1),
  (112,'00/01',1,12,'Valencia','Oviedo',2,0),
  (113,'00/01',1,12,'Málaga','Alavés',3,1),
  (114,'00/01',1,12,'Ath. Bilbao','Rayo Vallecano',4,2),
  (115,'00/01',1,12,'Rac. Santander','Espanyol',1,2),
  (116,'00/01',1,12,'Dptivo. Coruña','Celta',1,0),
  (117,'00/01',1,12,'Barcelona','Osasuna',2,0),
  (118,'00/01',1,12,'Real Madrid','Zaragoza',3,0),
  (119,'00/01',1,12,'Mallorca','Villarreal',2,1),
  (120,'00/01',1,12,'Numancia','Las Palmas',0,1),
  (121,'00/01',1,13,'Valladolid','Valencia',0,0),
  (122,'00/01',1,13,'Oviedo','Málaga',3,2),
  (123,'00/01',1,13,'Alavés','Ath. Bilbao',2,1),
  (124,'00/01',1,13,'Rayo Vallecano','Rac. Santander',4,1),
  (125,'00/01',1,13,'Espanyol','Dptivo. Coruña',0,2),
  (126,'00/01',1,13,'Celta','Barcelona',3,3),
  (127,'00/01',1,13,'Osasuna','Real Madrid',2,3),
  (128,'00/01',1,13,'Zaragoza','Mallorca',1,1),
  (129,'00/01',1,13,'Villarreal','Numancia',0,0),
  (130,'00/01',1,13,'Real Sociedad','Las Palmas',1,1),
  (131,'00/01',1,14,'Valencia','Real Sociedad',2,0),
  (132,'00/01',1,14,'Málaga','Valladolid',3,1),
  (133,'00/01',1,14,'Ath. Bilbao','Oviedo',4,0),
  (134,'00/01',1,14,'Rac. Santander','Alavés',2,1),
  (135,'00/01',1,14,'Dptivo. Coruña','Rayo Vallecano',1,1),
  (136,'00/01',1,14,'Barcelona','Espanyol',4,2),
  (137,'00/01',1,14,'Real Madrid','Celta',3,0),
  (138,'00/01',1,14,'Mallorca','Osasuna',1,1),
  (139,'00/01',1,14,'Numancia','Zaragoza',1,1),
  (140,'00/01',1,14,'Las Palmas','Villarreal',1,5),
  (141,'00/01',1,15,'Valencia','Málaga',2,0),
  (142,'00/01',1,15,'Valladolid','Ath. Bilbao',0,0),
  (143,'00/01',1,15,'Oviedo','Rac. Santander',1,0),
  (144,'00/01',1,15,'Alavés','Dptivo. Coruña',3,1),
  (145,'00/01',1,15,'Rayo Vallecano','Barcelona',2,2),
  (146,'00/01',1,15,'Espanyol','Real Madrid',1,2),
  (147,'00/01',1,15,'Celta','Mallorca',2,2),
  (148,'00/01',1,15,'Osasuna','Numancia',2,0),
  (149,'00/01',1,15,'Zaragoza','Las Palmas',3,1),
  (150,'00/01',1,15,'Real Sociedad','Villarreal',0,2),
  (151,'00/01',1,16,'Málaga','Real Sociedad',3,0),
  (152,'00/01',1,16,'Ath. Bilbao','Valencia',1,1),
  (153,'00/01',1,16,'Rac. Santander','Valladolid',2,2),
  (154,'00/01',1,16,'Dptivo. Coruña','Oviedo',3,0),
  (155,'00/01',1,16,'Barcelona','Alavés',3,2),
  (156,'00/01',1,16,'Real Madrid','Rayo Vallecano',3,1),
  (157,'00/01',1,16,'Mallorca','Espanyol',3,2),
  (158,'00/01',1,16,'Numancia','Celta',4,2),
  (159,'00/01',1,16,'Las Palmas','Osasuna',3,2),
  (160,'00/01',1,16,'Villarreal','Zaragoza',1,1),
  (161,'00/01',1,17,'Málaga','Ath. Bilbao',2,1),
  (162,'00/01',1,17,'Valencia','Rac. Santander',1,0),
  (163,'00/01',1,17,'Valladolid','Dptivo. Coruña',3,1),
  (164,'00/01',1,17,'Oviedo','Barcelona',2,3),
  (165,'00/01',1,17,'Alavés','Real Madrid',1,3),
  (166,'00/01',1,17,'Rayo Vallecano','Mallorca',2,2),
  (167,'00/01',1,17,'Espanyol','Numancia',2,0),
  (168,'00/01',1,17,'Celta','Las Palmas',0,1),
  (169,'00/01',1,17,'Osasuna','Villarreal',1,0),
  (170,'00/01',1,17,'Real Sociedad','Zaragoza',1,1),
  (171,'00/01',1,18,'Real Sociedad','Ath. Bilbao',0,2),
  (172,'00/01',1,18,'Rac. Santander','Málaga',0,1),
  (173,'00/01',1,18,'Dptivo. Coruña','Valencia',2,0),
  (174,'00/01',1,18,'Barcelona','Valladolid',3,1),
  (175,'00/01',1,18,'Real Madrid','Oviedo',4,0),
  (176,'00/01',1,18,'Mallorca','Alavés',4,3),
  (177,'00/01',1,18,'Numancia','Rayo Vallecano',0,2),
  (178,'00/01',1,18,'Las Palmas','Espanyol',1,0),
  (179,'00/01',1,18,'Villarreal','Celta',2,0),
  (180,'00/01',1,18,'Zaragoza','Osasuna',4,2),
  (181,'00/01',1,19,'Ath. Bilbao','Rac. Santander',3,1),
  (182,'00/01',1,19,'Málaga','Dptivo. Coruña',1,3),
  (183,'00/01',1,19,'Valencia','Barcelona',0,1),
  (184,'00/01',1,19,'Valladolid','Real Madrid',2,2),
  (185,'00/01',1,19,'Oviedo','Mallorca',1,1),
  (186,'00/01',1,19,'Alavés','Numancia',0,2),
  (187,'00/01',1,19,'Rayo Vallecano','Las Palmas',1,1),
  (188,'00/01',1,19,'Espanyol','Villarreal',2,1),
  (189,'00/01',1,19,'Celta','Zaragoza',1,1),
  (190,'00/01',1,19,'Osasuna','Real Sociedad',1,1),
  (191,'00/01',1,20,'Celta','Osasuna',1,0),
  (192,'00/01',1,20,'Espanyol','Zaragoza',5,0),
  (193,'00/01',1,20,'Rayo Vallecano','Villarreal',0,1),
  (194,'00/01',1,20,'Alavés','Las Palmas',1,0),
  (195,'00/01',1,20,'Oviedo','Numancia',3,0),
  (196,'00/01',1,20,'Valladolid','Mallorca',2,0),
  (197,'00/01',1,20,'Valencia','Real Madrid',0,1),
  (198,'00/01',1,20,'Málaga','Barcelona',0,0),
  (199,'00/01',1,20,'Ath. Bilbao','Dptivo. Coruña',2,2),
  (200,'00/01',1,20,'Rac. Santander','Real Sociedad',1,4),
  (201,'00/01',1,21,'Real Sociedad','Celta',2,2),
  (202,'00/01',1,21,'Osasuna','Espanyol',1,3),
  (203,'00/01',1,21,'Zaragoza','Rayo Vallecano',6,1),
  (204,'00/01',1,21,'Villarreal','Alavés',2,0),
  (205,'00/01',1,21,'Las Palmas','Oviedo',1,0),
  (206,'00/01',1,21,'Numancia','Valladolid',0,0),
  (207,'00/01',1,21,'Mallorca','Valencia',2,2),
  (208,'00/01',1,21,'Real Madrid','Málaga',4,3),
  (209,'00/01',1,21,'Barcelona','Ath. Bilbao',7,0),
  (210,'00/01',1,21,'Dptivo. Coruña','Rac. Santander',2,1),
  (211,'00/01',1,22,'Espanyol','Celta',0,1),
  (212,'00/01',1,22,'Rayo Vallecano','Osasuna',2,1),
  (213,'00/01',1,22,'Alavés','Zaragoza',1,0),
  (214,'00/01',1,22,'Oviedo','Villarreal',1,3),
  (215,'00/01',1,22,'Valladolid','Las Palmas',1,0),
  (216,'00/01',1,22,'Valencia','Numancia',3,0),
  (217,'00/01',1,22,'Málaga','Mallorca',0,1),
  (218,'00/01',1,22,'Ath. Bilbao','Real Madrid',1,0),
  (219,'00/01',1,22,'Rac. Santander','Barcelona',4,0),
  (220,'00/01',1,22,'Dptivo. Coruña','Real Sociedad',4,1),
  (221,'00/01',1,23,'Real Sociedad','Espanyol',2,1),
  (222,'00/01',1,23,'Celta','Rayo Vallecano',1,1),
  (223,'00/01',1,23,'Osasuna','Alavés',0,1),
  (224,'00/01',1,23,'Zaragoza','Oviedo',5,2),
  (225,'00/01',1,23,'Villarreal','Valladolid',2,1),
  (226,'00/01',1,23,'Las Palmas','Valencia',0,2),
  (227,'00/01',1,23,'Numancia','Málaga',3,2),
  (228,'00/01',1,23,'Mallorca','Ath. Bilbao',1,0),
  (229,'00/01',1,23,'Real Madrid','Rac. Santander',1,0),
  (230,'00/01',1,23,'Barcelona','Dptivo. Coruña',2,3),
  (231,'00/01',1,24,'Rayo Vallecano','Espanyol',1,1),
  (232,'00/01',1,24,'Alavés','Celta',2,2),
  (233,'00/01',1,24,'Oviedo','Osasuna',2,3),
  (234,'00/01',1,24,'Valladolid','Zaragoza',2,0),
  (235,'00/01',1,24,'Valencia','Villarreal',3,1),
  (236,'00/01',1,24,'Málaga','Las Palmas',2,1),
  (237,'00/01',1,24,'Ath. Bilbao','Numancia',3,1),
  (238,'00/01',1,24,'Rac. Santander','Mallorca',2,1),
  (239,'00/01',1,24,'Dptivo. Coruña','Real Madrid',2,2),
  (240,'00/01',1,24,'Barcelona','Real Sociedad',3,0),
  (241,'00/01',1,25,'Real Sociedad','Rayo Vallecano',2,0),
  (242,'00/01',1,25,'Espanyol','Alavés',0,0),
  (243,'00/01',1,25,'Celta','Oviedo',1,0),
  (244,'00/01',1,25,'Osasuna','Valladolid',2,1),
  (245,'00/01',1,25,'Zaragoza','Valencia',1,1),
  (246,'00/01',1,25,'Villarreal','Málaga',1,2),
  (247,'00/01',1,25,'Las Palmas','Ath. Bilbao',0,0),
  (248,'00/01',1,25,'Numancia','Rac. Santander',1,0),
  (249,'00/01',1,25,'Mallorca','Dptivo. Coruña',2,1),
  (250,'00/01',1,25,'Real Madrid','Barcelona',2,2),
  (251,'00/01',1,26,'Alavés','Rayo Vallecano',4,2),
  (252,'00/01',1,26,'Oviedo','Espanyol',2,2),
  (253,'00/01',1,26,'Valladolid','Celta',1,2),
  (254,'00/01',1,26,'Valencia','Osasuna',1,0),
  (255,'00/01',1,26,'Málaga','Zaragoza',2,0),
  (256,'00/01',1,26,'Ath. Bilbao','Villarreal',1,1),
  (257,'00/01',1,26,'Rac. Santander','Las Palmas',2,1),
  (258,'00/01',1,26,'Dptivo. Coruña','Numancia',4,1),
  (259,'00/01',1,26,'Barcelona','Mallorca',1,1),
  (260,'00/01',1,26,'Real Madrid','Real Sociedad',4,0),
  (261,'00/01',1,27,'Real Sociedad','Alavés',1,1),
  (262,'00/01',1,27,'Rayo Vallecano','Oviedo',0,2),
  (263,'00/01',1,27,'Espanyol','Valladolid',1,0),
  (264,'00/01',1,27,'Celta','Valencia',3,2),
  (265,'00/01',1,27,'Osasuna','Málaga',3,3),
  (266,'00/01',1,27,'Zaragoza','Ath. Bilbao',2,2),
  (267,'00/01',1,27,'Villarreal','Rac. Santander',4,2),
  (268,'00/01',1,27,'Las Palmas','Dptivo. Coruña',2,0),
  (269,'00/01',1,27,'Numancia','Barcelona',1,1),
  (270,'00/01',1,27,'Mallorca','Real Madrid',1,0),
  (271,'00/01',1,28,'Oviedo','Alavés',3,3),
  (272,'00/01',1,28,'Valladolid','Rayo Vallecano',1,3),
  (273,'00/01',1,28,'Valencia','Espanyol',0,1),
  (274,'00/01',1,28,'Málaga','Celta',1,4),
  (275,'00/01',1,28,'Ath. Bilbao','Osasuna',0,1),
  (276,'00/01',1,28,'Rac. Santander','Zaragoza',2,1),
  (277,'00/01',1,28,'Dptivo. Coruña','Villarreal',4,2),
  (278,'00/01',1,28,'Barcelona','Las Palmas',4,1),
  (279,'00/01',1,28,'Real Madrid','Numancia',1,0),
  (280,'00/01',1,28,'Mallorca','Real Sociedad',1,1),
  (281,'00/01',1,29,'Real Sociedad','Oviedo',3,0),
  (282,'00/01',1,29,'Alavés','Valladolid',4,2),
  (283,'00/01',1,29,'Rayo Vallecano','Valencia',1,4),
  (284,'00/01',1,29,'Espanyol','Málaga',1,2),
  (285,'00/01',1,29,'Celta','Ath. Bilbao',2,1),
  (286,'00/01',1,29,'Osasuna','Rac. Santander',1,1),
  (287,'00/01',1,29,'Zaragoza','Dptivo. Coruña',2,1),
  (288,'00/01',1,29,'Villarreal','Barcelona',4,4),
  (289,'00/01',1,29,'Las Palmas','Real Madrid',0,1),
  (290,'00/01',1,29,'Numancia','Mallorca',0,2),
  (291,'00/01',1,30,'Valladolid','Oviedo',1,0),
  (292,'00/01',1,30,'Valencia','Alavés',1,2),
  (293,'00/01',1,30,'Málaga','Rayo Vallecano',1,1),
  (294,'00/01',1,30,'Ath. Bilbao','Espanyol',0,1),
  (295,'00/01',1,30,'Rac. Santander','Celta',3,0),
  (296,'00/01',1,30,'Dptivo. Coruña','Osasuna',2,1),
  (297,'00/01',1,30,'Barcelona','Zaragoza',4,4),
  (298,'00/01',1,30,'Real Madrid','Villarreal',4,0),
  (299,'00/01',1,30,'Mallorca','Las Palmas',2,1),
  (300,'00/01',1,30,'Numancia','Real Sociedad',3,3),
  (301,'00/01',1,31,'Real Sociedad','Valladolid',3,1),
  (302,'00/01',1,31,'Oviedo','Valencia',0,0),
  (303,'00/01',1,31,'Alavés','Málaga',1,2),
  (304,'00/01',1,31,'Rayo Vallecano','Ath. Bilbao',1,2),
  (305,'00/01',1,31,'Espanyol','Rac. Santander',3,0),
  (306,'00/01',1,31,'Celta','Dptivo. Coruña',2,1),
  (307,'00/01',1,31,'Osasuna','Barcelona',3,1),
  (308,'00/01',1,31,'Zaragoza','Real Madrid',2,3),
  (309,'00/01',1,31,'Villarreal','Mallorca',2,2),
  (310,'00/01',1,31,'Las Palmas','Numancia',1,1),
  (311,'00/01',1,32,'Valencia','Valladolid',1,0),
  (312,'00/01',1,32,'Málaga','Oviedo',2,2),
  (313,'00/01',1,32,'Ath. Bilbao','Alavés',2,0),
  (314,'00/01',1,32,'Rac. Santander','Rayo Vallecano',1,1),
  (315,'00/01',1,32,'Dptivo. Coruña','Espanyol',1,0),
  (316,'00/01',1,32,'Barcelona','Celta',1,1),
  (317,'00/01',1,32,'Real Madrid','Osasuna',1,1),
  (318,'00/01',1,32,'Mallorca','Zaragoza',2,1),
  (319,'00/01',1,32,'Numancia','Villarreal',1,3),
  (320,'00/01',1,32,'Las Palmas','Real Sociedad',2,1),
  (321,'00/01',1,33,'Real Sociedad','Valencia',1,2),
  (322,'00/01',1,33,'Valladolid','Málaga',0,0),
  (323,'00/01',1,33,'Oviedo','Ath. Bilbao',5,0),
  (324,'00/01',1,33,'Alavés','Rac. Santander',5,1),
  (325,'00/01',1,33,'Rayo Vallecano','Dptivo. Coruña',1,1),
  (326,'00/01',1,33,'Espanyol','Barcelona',0,0),
  (327,'00/01',1,33,'Celta','Real Madrid',3,0),
  (328,'00/01',1,33,'Osasuna','Mallorca',1,0),
  (329,'00/01',1,33,'Zaragoza','Numancia',3,1),
  (330,'00/01',1,33,'Villarreal','Las Palmas',2,1),
  (331,'00/01',1,34,'Málaga','Valencia',3,0),
  (332,'00/01',1,34,'Ath. Bilbao','Valladolid',1,1),
  (333,'00/01',1,34,'Rac. Santander','Oviedo',2,0),
  (334,'00/01',1,34,'Dptivo. Coruña','Alavés',2,1),
  (335,'00/01',1,34,'Barcelona','Rayo Vallecano',5,1),
  (336,'00/01',1,34,'Real Madrid','Espanyol',2,2),
  (337,'00/01',1,34,'Mallorca','Celta',2,0),
  (338,'00/01',1,34,'Numancia','Osasuna',1,0),
  (339,'00/01',1,34,'Las Palmas','Zaragoza',2,1),
  (340,'00/01',1,34,'Villarreal','Real Sociedad',1,3),
  (341,'00/01',1,35,'Real Sociedad','Málaga',4,0),
  (342,'00/01',1,35,'Valencia','Ath. Bilbao',1,0),
  (343,'00/01',1,35,'Valladolid','Rac. Santander',1,1),
  (344,'00/01',1,35,'Oviedo','Dptivo. Coruña',2,3),
  (345,'00/01',1,35,'Alavés','Barcelona',0,1),
  (346,'00/01',1,35,'Rayo Vallecano','Real Madrid',0,1),
  (347,'00/01',1,35,'Espanyol','Mallorca',0,1),
  (348,'00/01',1,35,'Celta','Numancia',1,1),
  (349,'00/01',1,35,'Osasuna','Las Palmas',3,3),
  (350,'00/01',1,35,'Zaragoza','Villarreal',0,0),
  (351,'00/01',1,36,'Ath. Bilbao','Málaga',1,3),
  (352,'00/01',1,36,'Rac. Santander','Valencia',1,1),
  (353,'00/01',1,36,'Dptivo. Coruña','Valladolid',1,2),
  (354,'00/01',1,36,'Barcelona','Oviedo',0,1),
  (355,'00/01',1,36,'Real Madrid','Alavés',5,0),
  (356,'00/01',1,36,'Mallorca','Rayo Vallecano',4,0),
  (357,'00/01',1,36,'Numancia','Espanyol',2,1),
  (358,'00/01',1,36,'Las Palmas','Celta',0,1),
  (359,'00/01',1,36,'Villarreal','Osasuna',2,0),
  (360,'00/01',1,36,'Zaragoza','Real Sociedad',1,1),
  (361,'00/01',1,37,'Ath. Bilbao','Real Sociedad',1,3),
  (362,'00/01',1,37,'Málaga','Rac. Santander',2,1),
  (363,'00/01',1,37,'Valencia','Dptivo. Coruña',0,1),
  (364,'00/01',1,37,'Valladolid','Barcelona',2,2),
  (365,'00/01',1,37,'Oviedo','Real Madrid',1,1),
  (366,'00/01',1,37,'Alavés','Mallorca',2,4),
  (367,'00/01',1,37,'Rayo Vallecano','Numancia',2,1),
  (368,'00/01',1,37,'Espanyol','Las Palmas',3,2),
  (369,'00/01',1,37,'Celta','Villarreal',1,0),
  (370,'00/01',1,37,'Osasuna','Zaragoza',1,0),
  (371,'00/01',1,38,'Rac. Santander','Ath. Bilbao',3,0),
  (372,'00/01',1,38,'Dptivo. Coruña','Málaga',4,0),
  (373,'00/01',1,38,'Barcelona','Valencia',3,2),
  (374,'00/01',1,38,'Real Madrid','Valladolid',2,1),
  (375,'00/01',1,38,'Mallorca','Oviedo',4,2),
  (376,'00/01',1,38,'Numancia','Alavés',2,1),
  (377,'00/01',1,38,'Las Palmas','Rayo Vallecano',1,0),
  (378,'00/01',1,38,'Villarreal','Espanyol',4,0),
  (379,'00/01',1,38,'Zaragoza','Celta',1,1),
  (380,'00/01',1,38,'Real Sociedad','Osasuna',0,1);
go
--insertamos los equipos
insert Equipos (Nombre, Pos_Juego_Limpio)
select  distinct EQUIPO_LOCAL, 0 from [Resumen 2001] order by 1
go
--La clasificación del juego limpio, es ficticia, le asigno el id
update Equipos set Pos_Juego_Limpio = IdEquipo
go

--Consolidación de los partidos
insert Partidos_Equipo
select IdPartido = ID, IdEquipo = E.IdEquipo, IdEquipo_Contrario = V.IdEquipo, Es_Local = 1,
  Goles_A_Favor = R.GOLES_LOCAL, Goles_En_Contra = R.GOLES_VISITANTE,
  Puntos = case
     when R.GOLES_LOCAL = R.GOLES_VISITANTE then 1
     when R.GOLES_LOCAL > R.GOLES_VISITANTE then 3
     when R.GOLES_LOCAL < R.GOLES_VISITANTE then 0 
 end
from
  [Resumen 2001]  R inner join
  Equipos E on R.EQUIPO_LOCAL = E.Nombre inner join
  Equipos V on R.EQUIPO_VISITANTE = V.Nombre
union all
select IdPartido = ID, IdEquipo = V.IdEquipo, IdEquipo_Contrario = E.IdEquipo, Es_Local = 0,
  Goles_A_Favor = R.GOLES_VISITANTE, Goles_En_Contra = R.GOLES_LOCAL,
  Puntos = case
     when R.GOLES_LOCAL = R.GOLES_VISITANTE then 1
     when R.GOLES_LOCAL > R.GOLES_VISITANTE then 0
     when R.GOLES_LOCAL < R.GOLES_VISITANTE then 3 
 end
from
  [Resumen 2001]  R inner join
  Equipos E on R.EQUIPO_LOCAL = E.Nombre inner join
  Equipos V on R.EQUIPO_VISITANTE = V.Nombre
Order by ID

go

--Procedimiento almacenado para actualizar la clasificación
alter proc p_Refrescar_Clasificacion as

set nocount on
--Construir la clasificación
truncate table Clasificacion

insert Clasificacion (IdEquipo, PJ, PG, PE, PP, GF, GC, DG, Puntos, Desempate)
select E.IdEquipo,
  PJ = count(IdPartido),
  PG = sum(case when Puntos = 3 then 1 else 0 end),
  PE = sum(case when Puntos = 1 then 1 else 0 end),
  PP = sum(case when Puntos = 0 then 1 else 0 end),
  GF = SUM(P.Goles_A_Favor),
  GC = sum(P.Goles_En_Contra),
  DG = SUM(P.Goles_A_Favor) - sum(P.Goles_En_Contra),
  Puntos = SUM(P.Puntos),
  Desempate = 0
from Equipos E inner join Partidos_Equipo P on E.IdEquipo = P.IdEquipo
group by E.IdEquipo

--Empates
while exists (select top 1 Puntos from Clasificacion where Desempate = 0 group by Puntos having COUNT(IdEquipo) > 1)
  begin
    begin tran
    ;with Clas as (
      select
        C.IdEquipo, DG, GF, E.Pos_Juego_Limpio
      from Clasificacion C inner join Equipos E on C.IdEquipo = E.IdEquipo
      where Puntos in (select top 1 Puntos from Clasificacion where Desempate = 0 group by Puntos having COUNT(IdEquipo) > 1))
      , Criterios as (
      select
        P.IdEquipo,
        Puntos = SUM(P.Puntos), --1er criterio
        DG = SUM(P.Goles_A_Favor) - SUM(Goles_En_Contra), --2º criterio
        DG_General = C.DG, --3er criterio
        GF_General = C.GF, --4º criterio
        C.Pos_Juego_Limpio --5º criterio
      from
        Partidos_Equipo P inner join
        Clas C on P.IdEquipo = C.IdEquipo
      where P.IdEquipo_Contrario in (select IdEquipo from Clas)
      group by P.IdEquipo, C.DG, C.GF, C.Pos_Juego_Limpio)
      , Desempate as (
      select IdEquipo,
        Desempate = ROW_NUMBER() over (order by Puntos desc, DG desc, DG_General desc, GF_General, Pos_Juego_Limpio asc)
      from Criterios)
      update C set Desempate = D.Desempate
      from Clasificacion C inner join Desempate D on C.IdEquipo = D.IdEquipo

    commit
  end
return 0
go

--Actualización de la clasificación
exec p_Refrescar_Clasificacion

--Obtención de la misma
select E.Nombre, PJ, PG, PE, PP, GF, GC, DG, Puntos
from
   Clasificacion C inner join Equipos E on C.IdEquipo = E.IdEquipo
order by Puntos desc, Desempate asc


Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies