none
ayuda con un query RRS feed

  • Pregunta

  • necesito un query que actualice en base a este escenario tengo dos tablas que interactuan, un grupo puede tener varios subgrupos ligados.RELACION 1 A MUCHOS
    Un subgrupo solo puede estar ligado a un grupo. RELACION uno A UNO
    un producto solo puede estar en un subgrupo, RELACION 1 A 1
    deseo que al momento de eliminar un subgrupo en este caso el subgrupo 01 valide el grupo que tiene asignado en este caso grupo 10 y si ese grupo a la vez tiene a mas de un subgrupo relacionado(2,3,4,5) , los productos que pertenecen a subgrupo a eliminar (01)se actualicen al idsubgrupo que tenga menos registros del grupo en este caso (2)producto (1,2,3) al finalizar deben pertecer al idsubgrupo(2)del grupo 10
    tabla grupos

    grupo           idsubgrupo    
    grupo 10        idsubgrupo=01
    grupo 10        idsubgrupo=02
    grupo 10       idsubgrupo=03
    grupo 9         idsubgrupo=04
    grupo 10       idsubgrupo=05

    tabla subgrupos

    columna      columna
    idsubgrupo        producto
    idsubgrupo=01  producto1
    idsubgrupo=01  producto2
    idsubgrupo=01  producto3
    idsubgrupo=02  producto4
    idsubgrupo=03  producto5
    idsubgrupo=03  producto6


    • Editado juanki724 miércoles, 25 de septiembre de 2019 20:34
    miércoles, 25 de septiembre de 2019 20:32

Respuestas

  • Hola Juanki724:

    El escenario

    create table grupos (grupo varchar(15), idsubgrupo varchar(15))
    go
    insert into grupos (grupo, idsubgrupo)
    values
    ('grupo 10','01'),
    ('grupo 10','02'),
    ('grupo 10','03'),
    ('grupo 9' ,'04'),
    ('grupo 10','05');
    go
    create table productos 
    (idsubgrupo varchar(15), producto varchar(15))
    go
    insert into productos
    (idsubgrupo, producto)
    values
    ('01','1'),
    ('01','2'),
    ('01','3'),
    ('02','4'),
    ('03','5'),
    ('03','6');

    Puedes hacer algo del estilo:

    BEGIN TRAN;
    DECLARE @idsubGrupoDelete VARCHAR(15)= '01';
    DECLARE @idsubgrupo VARCHAR(15);
    WITH cte
         AS (SELECT g.grupo, 
                    g.idsubgrupo, 
                    p.producto
             FROM grupos g
                  INNER JOIN productos p ON p.idsubgrupo = g.idsubgrupo
             WHERE p.idsubgrupo = @idsubGrupoDelete),
         agrupado
         AS (SELECT g.idsubgrupo, 
                    COUNT(DISTINCT p.producto) AS veces
             FROM grupos g
                  INNER JOIN cte c ON g.grupo = c.grupo
                  INNER JOIN productos p ON g.idsubgrupo = p.idsubgrupo
             WHERE g.idsubgrupo <> @idsubGrupoDelete
             GROUP BY g.idsubgrupo),
         minimo
         AS (SELECT TOP (1) idsubgrupo
             FROM agrupado
             ORDER BY veces)
         SELECT @idsubgrupo = m.idsubgrupo
         FROM minimo m;
    DELETE FROM GRUPOS
    WHERE idsubgrupo = @idsubGrupoDelete;
    UPDATE p
      SET 
          idsubgrupo = @idsubgrupo
    FROM productos p
    WHERE p.idsubgrupo = @idsubGrupoDelete;
    IF(@@ERROR = 0)
        BEGIN
            COMMIT TRAN;
    END;
        ELSE
        BEGIN
            ROLLBACK TRAN;
    END;

    Resultado

    • Marcado como respuesta juanki724 miércoles, 25 de septiembre de 2019 21:48
    miércoles, 25 de septiembre de 2019 21:25
  • Hola juanki724:

    Solo tienes que cambiar INNER JOIN productos por LEFT JOIN 

     drop table if exists grupos;
    create table grupos (grupo varchar(15), idsubgrupo varchar(15))
    go
    insert into grupos (grupo, idsubgrupo)
    values
    ('grupo 10','01'),
    ('grupo 10','02'),
    ('grupo 10','03'),
    ('grupo 9' ,'04'),
    ('grupo 10','05');
    go
    drop table if exists productos
    create table productos 
    (idsubgrupo varchar(15), producto varchar(15))
    go
    insert into productos
    (idsubgrupo, producto)
    values
    ('01','1'),
    ('01','2'),
    ('01','3');
    go
    BEGIN TRAN;
    DECLARE @idsubGrupoDelete VARCHAR(15)= '01';
    DECLARE @idsubgrupo VARCHAR(15);
    WITH cte
         AS (SELECT g.grupo, 
                    g.idsubgrupo, 
                    p.producto
             FROM grupos g
                  INNER JOIN productos p ON p.idsubgrupo = g.idsubgrupo
             WHERE p.idsubgrupo = @idsubGrupoDelete),
         agrupado
         AS (SELECT g.idsubgrupo, 
                    COUNT(DISTINCT p.producto) AS veces
             FROM grupos g
                  INNER JOIN cte c ON g.grupo = c.grupo
                  LEFT JOIN productos p ON g.idsubgrupo = p.idsubgrupo
             WHERE g.idsubgrupo <> @idsubGrupoDelete
             GROUP BY g.idsubgrupo),
         minimo
         AS (SELECT TOP (1) idsubgrupo
             FROM agrupado
             ORDER BY veces)
         SELECT @idsubgrupo = m.idsubgrupo
         FROM minimo m;
    DELETE FROM GRUPOS
    WHERE idsubgrupo = @idsubGrupoDelete;
    UPDATE p
      SET 
          idsubgrupo = @idsubgrupo
    FROM productos p
    WHERE p.idsubgrupo = @idsubGrupoDelete;
    IF(@@ERROR = 0)
        BEGIN
            COMMIT TRAN;
    END;
        ELSE
        BEGIN
            ROLLBACK TRAN;
    END;
    

    Salida

    • Marcado como respuesta juanki724 jueves, 26 de septiembre de 2019 14:29
    miércoles, 25 de septiembre de 2019 23:21

Todas las respuestas

  • Hola Juanki724:

    El escenario

    create table grupos (grupo varchar(15), idsubgrupo varchar(15))
    go
    insert into grupos (grupo, idsubgrupo)
    values
    ('grupo 10','01'),
    ('grupo 10','02'),
    ('grupo 10','03'),
    ('grupo 9' ,'04'),
    ('grupo 10','05');
    go
    create table productos 
    (idsubgrupo varchar(15), producto varchar(15))
    go
    insert into productos
    (idsubgrupo, producto)
    values
    ('01','1'),
    ('01','2'),
    ('01','3'),
    ('02','4'),
    ('03','5'),
    ('03','6');

    Puedes hacer algo del estilo:

    BEGIN TRAN;
    DECLARE @idsubGrupoDelete VARCHAR(15)= '01';
    DECLARE @idsubgrupo VARCHAR(15);
    WITH cte
         AS (SELECT g.grupo, 
                    g.idsubgrupo, 
                    p.producto
             FROM grupos g
                  INNER JOIN productos p ON p.idsubgrupo = g.idsubgrupo
             WHERE p.idsubgrupo = @idsubGrupoDelete),
         agrupado
         AS (SELECT g.idsubgrupo, 
                    COUNT(DISTINCT p.producto) AS veces
             FROM grupos g
                  INNER JOIN cte c ON g.grupo = c.grupo
                  INNER JOIN productos p ON g.idsubgrupo = p.idsubgrupo
             WHERE g.idsubgrupo <> @idsubGrupoDelete
             GROUP BY g.idsubgrupo),
         minimo
         AS (SELECT TOP (1) idsubgrupo
             FROM agrupado
             ORDER BY veces)
         SELECT @idsubgrupo = m.idsubgrupo
         FROM minimo m;
    DELETE FROM GRUPOS
    WHERE idsubgrupo = @idsubGrupoDelete;
    UPDATE p
      SET 
          idsubgrupo = @idsubgrupo
    FROM productos p
    WHERE p.idsubgrupo = @idsubGrupoDelete;
    IF(@@ERROR = 0)
        BEGIN
            COMMIT TRAN;
    END;
        ELSE
        BEGIN
            ROLLBACK TRAN;
    END;

    Resultado

    • Marcado como respuesta juanki724 miércoles, 25 de septiembre de 2019 21:48
    miércoles, 25 de septiembre de 2019 21:25
  • quedo casi perfecto bro muchas gracias, pero  si deseo eliminar ese subgrupo 01, que pertenece al grupo ejemplo 10, pero tiene 2 subgrupos adicionales al 01  pero estos dos  no tienen aun asignado productos, bajo este escenario no realiza el update para asignarle algun idsubgrupo de los dos posibles.el caso es que si existe por lo menos 2 subgrupos del grupo asignado al eliminar debe pasarse al restante o al que tenga menos productos no debe quedar vacio o si idsubgrupo
    miércoles, 25 de septiembre de 2019 22:37
  • Hola juanki724:

    Solo tienes que cambiar INNER JOIN productos por LEFT JOIN 

     drop table if exists grupos;
    create table grupos (grupo varchar(15), idsubgrupo varchar(15))
    go
    insert into grupos (grupo, idsubgrupo)
    values
    ('grupo 10','01'),
    ('grupo 10','02'),
    ('grupo 10','03'),
    ('grupo 9' ,'04'),
    ('grupo 10','05');
    go
    drop table if exists productos
    create table productos 
    (idsubgrupo varchar(15), producto varchar(15))
    go
    insert into productos
    (idsubgrupo, producto)
    values
    ('01','1'),
    ('01','2'),
    ('01','3');
    go
    BEGIN TRAN;
    DECLARE @idsubGrupoDelete VARCHAR(15)= '01';
    DECLARE @idsubgrupo VARCHAR(15);
    WITH cte
         AS (SELECT g.grupo, 
                    g.idsubgrupo, 
                    p.producto
             FROM grupos g
                  INNER JOIN productos p ON p.idsubgrupo = g.idsubgrupo
             WHERE p.idsubgrupo = @idsubGrupoDelete),
         agrupado
         AS (SELECT g.idsubgrupo, 
                    COUNT(DISTINCT p.producto) AS veces
             FROM grupos g
                  INNER JOIN cte c ON g.grupo = c.grupo
                  LEFT JOIN productos p ON g.idsubgrupo = p.idsubgrupo
             WHERE g.idsubgrupo <> @idsubGrupoDelete
             GROUP BY g.idsubgrupo),
         minimo
         AS (SELECT TOP (1) idsubgrupo
             FROM agrupado
             ORDER BY veces)
         SELECT @idsubgrupo = m.idsubgrupo
         FROM minimo m;
    DELETE FROM GRUPOS
    WHERE idsubgrupo = @idsubGrupoDelete;
    UPDATE p
      SET 
          idsubgrupo = @idsubgrupo
    FROM productos p
    WHERE p.idsubgrupo = @idsubGrupoDelete;
    IF(@@ERROR = 0)
        BEGIN
            COMMIT TRAN;
    END;
        ELSE
        BEGIN
            ROLLBACK TRAN;
    END;
    

    Salida

    • Marcado como respuesta juanki724 jueves, 26 de septiembre de 2019 14:29
    miércoles, 25 de septiembre de 2019 23:21
  • eres un genio mil gracias bro, me has salvado :)
    jueves, 26 de septiembre de 2019 14:29