none
Update en tabla comprobando valores RRS feed

  • Pregunta

  • Buenas de nuevo,

    Sigo con el proyecto que estoy desarrollando y me encuentro con otra duda.

    1) Tengo una tabla de partidos con estos campos : IdJornada,EquipoL,ResL,EquipoV,ResV,Estado

    2) Tengo otra tabla que es la clasificacion donde registro los datos : Equipo,Pts,PJ,PG,PE,PP,GF,GC

    Muestro los partidos en un gridview y edito los resultados poniendo el marcador y el estado del partido como Final.

    Lo que necesito es que al actualizar este partido, automaticamente me haga los calculos y realice el update en la tabla clasificacion:

    Me explico un poco mejor poniendo un ejemplo:

    1) 1 - FC Barcelona 5 Madrid 2 Final

    2) Tengo que comprobar si el Estado es igual a Final. Si lo es:

    2.1) Tengo que comprobar si ResL>ResV (Equipo Local Gana) entonces:

    2.2) Calculos EquipoL: Tengo que sumar 3 puntos, Tengo que sumar 1 a PJ, Tengo que sumar 1 a PG y por ultimo sumar 5 a GF y sumar 2 a GC.

    2.3) Calculos EquipoV : Tengo que sumar 1 a PJ,Tengo que sumar 1 a PP, Sumar 2 a GF y sumar 5 a GC.

    3) Una vez tengo todos los calculos tendría que realizar el update a la tabla clasificación.

    Tendría que hacer lo mismo para el caso de empatar y de que gane el equipo visitante pero si tengo claro un caso los otros no serán complicados.

    Espero que alguien me pueda ayudar un poco.

    Un saludo y gracias

    lunes, 28 de septiembre de 2015 7:51

Todas las respuestas

  • Tendrías que tener en cuenta bastantes cosas. Efectivamente cuando cambias el estado del partido a Final se añadirían los puntos, partidos jugados, goles, etc. Pero ¿qué sucedería si después de marcado como finalizado un partido corriges el resultado? Deberían restarse los valores añadidos anteriormente y añadir los nuevos, con lo que necesitarías tener en cuenta no sólo los datos que estás grabando si no también los que existían antes de actualizar.

    Esto es un problema típico cuando tienes información redundante en tus tablas. ¿Para qué crear una tabla Clasificacion si toda la información de esta tabla puede calcularse a partir de la de Partidos?

    Yo te recomendaría que Clasificacion fuera una vista que calculase los valores a partir del contenido de la tabla Partidos.

    Échale un vistazo a este ejemplo:

    CREATE TABLE [Partidos](
    	[IdJornada] [int] NOT NULL,
    	[EquipoL] [varchar](50) NOT NULL,
    	[ResL] [int] NULL,
    	[EquipoV] [varchar](50) NOT NULL,
    	[ResV] [int] NULL,
    	[Estado] [varchar](50) NULL,
     CONSTRAINT [PK_Partidos] PRIMARY KEY CLUSTERED 
    (
    	[IdJornada] ASC,
    	[EquipoL] ASC
    ))
    
    GO
    
    INSERT INTO Partidos (IdJornada, EquipoL, ResL, EquipoV, ResV, Estado)
    VALUES (1, 'Athletic', 4, 'FC Barcelona', 0, 'Final')
    GO
    INSERT INTO Partidos (IdJornada, EquipoL, ResL, EquipoV, ResV, Estado)
    VALUES (2, 'FC Barcelona', 5, 'Madrid', 2, 'Final')
    GO
    
    CREATE VIEW Clasificacion AS
    WITH Equipos AS (SELECT DISTINCT EquipoL AS Equipo FROM Partidos
    	UNION SELECT DISTINCT EquipoV FROM Partidos)
    SELECT Equipos.Equipo,
    	SUM(CASE WHEN Partidos.ResL=Partidos.ResV THEN 1
    		WHEN Partidos.ResL>Partidos.ResV AND Partidos.EquipoL=Equipos.Equipo THEN 3
    		WHEN Partidos.ResL<Partidos.ResV AND Partidos.EquipoV=Equipos.Equipo THEN 3
    		ELSE 0 END) AS Pts,
    	COUNT(Partidos.IdJornada) AS PJ,
    	SUM(CASE WHEN Partidos.ResL>Partidos.Resv AND Partidos.EquipoL=Equipos.Equipo THEN 1
    		WHEN Partidos.ResV>Partidos.ResL AND Partidos.EquipoV=Equipos.Equipo THEN 1
    		ELSE 0 END) AS PG,
    	SUM(CASE WHEN Partidos.ResL=Partidos.Resv THEN 1
    		ELSE 0 END) AS PE,
    	SUM(CASE WHEN Partidos.ResL>Partidos.Resv AND Partidos.EquipoV=Equipos.Equipo THEN 1
    		WHEN Partidos.ResV>Partidos.ResL AND Partidos.EquipoL=Equipos.Equipo THEN 1
    		ELSE 0 END) AS PP,
    	SUM(CASE WHEN Partidos.EquipoL=Equipos.Equipo THEN ResL ELSE ResV END) AS GF,
    	SUM(CASE WHEN Partidos.EquipoL=Equipos.Equipo THEN ResV ELSE ResL END) AS GC
    FROM Equipos
    INNER JOIN Partidos ON Partidos.EquipoL=Equipos.Equipo OR Partidos.EquipoV=Equipos.Equipo
    WHERE Partidos.Estado='Final'
    GROUP BY Equipos.Equipo;
    GO
    
    SELECT * FROM Clasificacion
    
    DROP VIEW Clasificacion;
    DROP TABLE Partidos;

    Evidentemente, el código de la vista se puede simplificar si tienes una tabla Equipos.


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    lunes, 28 de septiembre de 2015 8:26
  • Ostras Asier la verdad que me parece muy interesante tu idea.

    ¿Esto lo tendria que hacer en un procedimiento? ¿o esto lo tendria que ejecutar cuando selecciono que me muestre la clasificación?

    Tengo una tabla equipos con : id,Nombre,Campo

    1) Yo muestro los resultados en un gridview.

    2) Realmente mis campos EquipoL/EquipoV en la tabla partidos los tengo como INT y los muestro con un inner join hacia la tabla equipos.

    3) ¿La Clasificacion entonces como la tendria que mostrar?

    Muchas gracias por la ayuda de verdad.

    Un saludo

    lunes, 28 de septiembre de 2015 10:50
  • No, ningún procedimiento.

    Simplemente te creas la vista Clasificacion que obtenga el resultado a partir de la tabla Partidos.

    A partir de ahí puedes utilizar la vista Clasificacion en tus consultas como si fuese una tabla más.


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    lunes, 28 de septiembre de 2015 11:07
  • Vale Asier creo que más o menos lo entiendo.

    Solo una cosa más:

    Tengo la tabla Equipos con id,Nombre,Campo,etc..

    La Vista me devuelve la clasificacion con el id del equipo.¿Como tendría que ponerla para que me saliera el nombre? Se que sería una inner join pero no sé exactamente donde lo tendría que poner.

    Ahora mismo tengo esto:

    CREATE VIEW VistaClasificacion AS
    WITH Teams AS (SELECT DISTINCT EquipoL AS Equipo FROM Partidos
    	UNION SELECT DISTINCT EquipoV FROM Partidos)
    SELECT Equipos.id,
    	SUM(CASE WHEN Partidos.ResL=Partidos.ResV THEN 1
    		WHEN Partidos.ResL>Partidos.ResV AND Partidos.EquipoL=Equipos.id THEN 3
    		WHEN Partidos.ResL<Partidos.ResV AND Partidos.EquipoV=Equipos.id THEN 3
    		ELSE 0 END) AS Pts,
    	COUNT(Partidos.IdJornada) AS PJ,
    	SUM(CASE WHEN Partidos.ResL>Partidos.Resv AND Partidos.EquipoL=Equipos.id THEN 1
    		WHEN Partidos.ResV>Partidos.ResL AND Partidos.EquipoV=Equipos.id THEN 1
    		ELSE 0 END) AS PG,
    	SUM(CASE WHEN Partidos.ResL=Partidos.Resv THEN 1
    		ELSE 0 END) AS PE,
    	SUM(CASE WHEN Partidos.ResL>Partidos.Resv AND Partidos.EquipoV=Equipos.id THEN 1
    		WHEN Partidos.ResV>Partidos.ResL AND Partidos.EquipoL=Equipos.id THEN 1
    		ELSE 0 END) AS PP,
    	SUM(CASE WHEN Partidos.EquipoL=Equipos.id THEN ResL ELSE ResV END) AS GF,
    	SUM(CASE WHEN Partidos.EquipoL=Equipos.id THEN ResV ELSE ResL END) AS GC
    FROM Equipos
    INNER JOIN Partidos ON Partidos.EquipoL=Equipos.id OR Partidos.EquipoV=Equipos.id
    WHERE Partidos.idEstado='4'
    GROUP BY Equipos.id;
    GO

    De nuevo muchas gracias.



    • Editado XuS lunes, 28 de septiembre de 2015 13:22
    lunes, 28 de septiembre de 2015 13:14
  • Es que al principio de la consulta defino una Common Table Expression con nombre Equipos. Al hacer referencia a Equipos te coge el resultado de la CTE en lugar de la tabla. Si tienes una tabla Equipos puedes prescindir de esa parte de la consulta:

    CREATE VIEW VistaClasificacion AS
    SELECT Equipos.id,
        SUM(CASE WHEN Partidos.ResL=Partidos.ResV THEN 1
            WHEN Partidos.ResL>Partidos.ResV AND Partidos.EquipoL=Equipos.id THEN 3
            WHEN Partidos.ResL<Partidos.ResV AND Partidos.EquipoV=Equipos.id THEN 3
            ELSE 0 END) AS Pts,
        COUNT(Partidos.IdJornada) AS PJ,
        SUM(CASE WHEN Partidos.ResL>Partidos.Resv AND Partidos.EquipoL=Equipos.id THEN 1
            WHEN Partidos.ResV>Partidos.ResL AND Partidos.EquipoV=Equipos.id THEN 1
            ELSE 0 END) AS PG,
        SUM(CASE WHEN Partidos.ResL=Partidos.Resv THEN 1
            ELSE 0 END) AS PE,
        SUM(CASE WHEN Partidos.ResL>Partidos.Resv AND Partidos.EquipoV=Equipos.id THEN 1
            WHEN Partidos.ResV>Partidos.ResL AND Partidos.EquipoL=Equipos.id THEN 1
            ELSE 0 END) AS PP,
        SUM(CASE WHEN Partidos.EquipoL=Equipos.id THEN ResL ELSE ResV END) AS GF,
        SUM(CASE WHEN Partidos.EquipoL=Equipos.id THEN ResV ELSE ResL END) AS GC
    FROM Equipos
    INNER JOIN Partidos ON Partidos.EquipoL=Equipos.id OR Partidos.EquipoV=Equipos.id
    WHERE Partidos.idEstado='4'
    GROUP BY Equipos.id;
    GO


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    lunes, 28 de septiembre de 2015 13:24
  • Y por último como lo tendría que ordenador por puntos? Cuando pongo ORDER BY me dice que la clausula no es válida para vista.

    Y para mostrar el Nombre del Equipo y no su id?

    Gracias y perdona con tanta pregunta.

    lunes, 28 de septiembre de 2015 13:30
  • Lo de los puntos lo he hecho cuando ejecuta la select de la vista.

    Ahora solo me faltaría el Nombre del Equipo y que saliera la posicion del 1 al 20.

    lunes, 28 de septiembre de 2015 13:32
  • Efectivamente la ordenación debes hacerla en la consulta.

    En cuanto al Nombre del Equipo podrías hacerlo también en la consulta haciendo una JOIN con Equipos o en la vista:

    CREATE VIEW VistaClasificacion AS
    SELECT Equipos.id,Equipos.Nombre,
        SUM(CASE WHEN Partidos.ResL=Partidos.ResV THEN 1
            WHEN Partidos.ResL>Partidos.ResV AND Partidos.EquipoL=Equipos.id THEN 3
            WHEN Partidos.ResL<Partidos.ResV AND Partidos.EquipoV=Equipos.id THEN 3
            ELSE 0 END) AS Pts,
        COUNT(Partidos.IdJornada) AS PJ,
        SUM(CASE WHEN Partidos.ResL>Partidos.Resv AND Partidos.EquipoL=Equipos.id THEN 1
            WHEN Partidos.ResV>Partidos.ResL AND Partidos.EquipoV=Equipos.id THEN 1
            ELSE 0 END) AS PG,
        SUM(CASE WHEN Partidos.ResL=Partidos.Resv THEN 1
            ELSE 0 END) AS PE,
        SUM(CASE WHEN Partidos.ResL>Partidos.Resv AND Partidos.EquipoV=Equipos.id THEN 1
            WHEN Partidos.ResV>Partidos.ResL AND Partidos.EquipoL=Equipos.id THEN 1
            ELSE 0 END) AS PP,
        SUM(CASE WHEN Partidos.EquipoL=Equipos.id THEN ResL ELSE ResV END) AS GF,
        SUM(CASE WHEN Partidos.EquipoL=Equipos.id THEN ResV ELSE ResL END) AS GC
    FROM Equipos
    INNER JOIN Partidos ON Partidos.EquipoL=Equipos.id OR Partidos.EquipoV=Equipos.id
    WHERE Partidos.idEstado='4'
    GROUP BY Equipos.id, Equipos.Nombre;
    GO

    En cuanto a la posición, podrías utilizar ROW_NUMBER:

    SELECT ROW_NUMBER() OVER (ORDER BY Pts DESC) AS Posicion, Nombre, Pts, PJ, PG, PE, PP, GF, GC
    FROM VistaClasificacion
    ORDER BY Pts DESC
    


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    lunes, 28 de septiembre de 2015 14:04
  • Ya está Asier. Creo que ya lo tengo.

    Muchas gracias por la ayuda la verdad.

    lunes, 28 de septiembre de 2015 15:39
  • Hola de nuevo,

    En principio tengo medio solucionado el problema gracias a la ayuda de Asier pero me encuentro con un detalle importante que no sé como tener en cuenta. El problema lo tengo cuando dos o más equipos están empatados a puntos.

    A ver si me puedo explicar:

    1) Tengo una liga de 10 equipos por ejemplo.

    2) Para ordenar la clasificacion sigo el siguiente criterio :

        a) Puntos

        b) Diferencia de Goles

        c) Goles a favor

        d) Por último, orden alfabético

    3) Esto es así hasta la segunda vuelta, es decir las primeras 5 jornadas el criterio de orden es correcto así, pero a partir de las siguientes el criterio cambia siendo así:

        a) Puntos

        b) Diferencia particular de goles (si los dos equipos han disputado los dos partidos entre si)

        c) Diferencia general de goles

        d) Goles a Favor

        e) Orden Alfabético

    Repito que los criterios para el orden de clasificación son : Puntos, Diferencia de Goles, Goles a Favor y orden alfabético pero cuando dos o más equipos están empatados a puntos tengo que añadir un criterio más.

    Espero haber explicado con detalle el problema.

    Muchas Gracias

    martes, 29 de septiembre de 2015 15:42
  • Hombre, eso ya me parece demasiada lógica para incluir en una consulta.

    Deberías implementarlo en la lógica de negocio de tu aplicación.


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    martes, 29 de septiembre de 2015 18:13
  • Lo siento Asier pero no entiendo cuando dices implementarlo en la lógica de mi negocio. ¿Podría hacer algo no tan completo? Es decir cuando pasen esos casos intentar cambiar el idPosicion de alguna manera?

    Por otro lado como puedo hacer para que en la consulta me aparezcan las posiciones? He visto que con el RANK lo podría realizar pero no lo veo muy claro.

    Gracias por todo.

    martes, 29 de septiembre de 2015 18:40
  • A lo que me refiero es que, en lugar de tratar de hacer una consulta SQL que te devuelva la clasificación ya montada, puedes descargar los resultados de los partidos y montar la clasificación en el código de tu aplicación (con VB.Net o C#, no sé qué utilizas).


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    miércoles, 30 de septiembre de 2015 8:28
  • Utilizo C#. La verdad que ahora si entiendo lo que me planteas pero no sé si por donde comenzar la verdad. Yo ahora mismo muestro la vista en un gridview. Tengo dos cosas:

    1) Como puedo mostrar en la consulta que ya me ayudaste a crear una columna con el número de posición. Del 1 al 20 en este caso.

    2) Como sería el proceso para implementarlo como dices?

    Lo siento por tanta pregunta.

    Un saludo y gracias

    miércoles, 30 de septiembre de 2015 10:16
  • El tema del punto 1 ya lo tengo solucionado. Me ha costado un poco montar la select aunque una vez hecho se entiende perfectamente.

    ¿Podrías  ayudarme a implementar una solución al criterio del orden de la clasificación?

    Un saludo y gracias

    miércoles, 30 de septiembre de 2015 21:22