locked
ayuda con query para hacer update

    Question

  • saludos estoy tratando de hacer una query para un update pero no me esta saliendo hasta el moento tengo algo asi

    	UPDATE CONTABILIDAD1
    	SET Filler='02'
    	FROM CONTABILIDAD1 C
    	INNER JOIN OPERACIONACTIVACALENDARIO OAC
    	ON  C.CodOperacion=OAC.CodOperacionActiva
    	INNER JOIN CREDITORECUPERACION CR
    	ON  C.CodOperacion=CR.CodOperacionActiva
    	WHERE 1=1
    		AND 
    		(OAC.EstadoCuotaCalendario in ('C')
    		OR
    		OAC.EstadoCuotaCalendario in ('G'))
    		AND (Select FechaHoy From FechaCierre)<OAC.FechaVencimientoCuota
    		AND OAC.NumCuotaCalendario=
    	   (SELECT MAX(OAC1.NumCuotaCalendario)
    		FROM CONTABILIDAD1 C1
    	    INNER JOIN OPERACIONACTIVACALENDARIO OAC1
    	    ON  C1.CodOperacion=OAC1.CodOperacionActiva
    	    WHERE 1=1
    		AND OAC1.EstadoCuotaCalendario in ('C')
    		GROUP BY C1.CodOperacion,OAC1.CodOperacionActiva)
    	    AND CR.EstadoRecuperacion='H'

    pero me vota el error

    Msg 512, Level 16, State 1, Line 1
    Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
    The statement has been terminated.

    Gracias.

    Friday, August 31, 2012 9:20 PM

Answers

All replies

  • En esta query estas seguro que solo retorno una fila FechaHOY?

    AND (Select FechaHoy From FechaCierre)<OAC.FechaVencimientoCuota

    PD: he visto ya a varios usuarios agregar en los wheres 1=1, para que ponen una sentencia que siempre será true?

    Friday, August 31, 2012 10:27 PM
  • esa si devuelve solo una fila ,le problema es aqui,

    AND OAC.NumCuotaCalendario=
      
    (SELECT MAX(OAC1.NumCuotaCalendario)

    este si devuelve mas de una fila, entonces quisiera saber de que otra manera logica puedo hacer lo que me propongo.

    Friday, August 31, 2012 10:30 PM
  • esa devuelve mas de una fila porque estas agrupando, necesitas esa agrupacion realmente?

    Si la necesitas podrias hacer esto

    AND OAC.NumCuotaCalendario IN
       (SELECT MAX(OAC1.NumCuotaCalendario)

    Friday, August 31, 2012 10:32 PM
  • Te agradezco la repuesta ya probe con in, se que no se cae pero tampoco devuleve los resultado esperados, voy aponer una query similar que probe yu los resultados que arroja

    	SELECT OAC.NumCuotaCalendario,*
    	 FROM
    	 CONTABILIDAD C
    	INNER JOIN OPERACIONACTIVACALENDARIO OAC
    	ON  C.CodOperacion=OAC.CodOperacionActiva
    	INNER JOIN CREDITORECUPERACION CR
    	ON  C.CodOperacion=CR.CodOperacionActiva
    	WHERE 1=1
    		AND OAC.EstadoCuotaCalendario IN ('C')
    		AND (Select FechaHoy From FechaCierre)>=OAC.FechaVencimientoCuota
    		AND (OAC.NumCuotaCalendario) IN
    	   (SELECT MAX(OAC1.NumCuotaCalendario)
    		FROM CONTABILIDAD C1
    	    INNER JOIN OPERACIONACTIVACALENDARIO OAC1
    	    ON  C1.CodOperacion=OAC1.CodOperacionActiva
    	    WHERE 1=1
    		AND OAC1.EstadoCuotaCalendario IN ('C')
    		GROUP BY OAC1.CodOperacionActiva)
    	    AND CR.EstadoRecuperacion='H'

    y arroja

    NumCuotaCalendario CodBanco CodApp CodMoneda CodTienda CodUnico
    1 3 MYP 10 100 50011380
    2 3 MYP 10 100 50011380
    3 3 MYP 10 100 50011380
    1 3 MYP 10 221 20
    2 3 MYP 10 221 20
    3 3 MYP 10 221 20
    4 3 MYP 10 221 20
    5 3 MYP 10 221 20
    6 3 MYP 10 221 20
    1 3 MYP 10 221 50020554
    1 3 MYP 10 221 50020554
    2 3 MYP 10 221 50020554
    3 3 MYP 10 221 50020554
    4 3 MYP 10 221 50020554
    5 3 MYP 10 221 50020554
    6 3 MYP 10 221 50020554

    como veràs no arroja el maximo numcuota de calendario, sino todos,

    Friday, August 31, 2012 10:42 PM
  • Como un consejo, al igual que cuando disenas un DELETE .... y se recomienda que primero verifiques el resultado a traves de un SELECT, igual pasa cuando realizas consultas correlacionadas, lo primero es que pruebes que el segmento en donde tienes ese MAX te retorne los resultados esperados como filtro de la consulta mas externa, en lo referido al codigo 1=1 yo unicamente lo he visto implementado en la construcción de SQL Dinamico para temas de filtros en condiciones WHERE, pero en este contexto realmente no tiene razon de ser.

    Seria mas facil para nosotros que siguieras los consejos posteando la estructuras y data de prueba, resulta menos complicado apoyarte.


    "How many years can some people exist before they're allowed to be free" Bob Dylan Email: info@geohernandez.com Blog: geeks.ms/blogs/ghernandez

    Friday, August 31, 2012 10:51 PM
  • Coincido con Geovanny -Gio- Hernandez, en mi experiencia siempre que hago un delete o un update através de un query complejo siempre verifico primero realizando un select solamente de ese query... ahora, con respecto a tu problema, nos puedes mostrar las estructuras de tus tablas, ejemplos del contenido de cada tabla y el resultado esperado ??

    SALU2!

    Friday, August 31, 2012 11:23 PM
  • gracias por las respuestas ,aunque no es necesario repetir lo mismo 2 veces

    Y ademas que me digan que haga lo que ya estoy haciendo,porque en mi penultimo post justamente hago un select a la tabla para ver que vota.

    en fin...


    • Edited by Augusto C Saturday, September 01, 2012 5:26 AM
    Saturday, September 01, 2012 5:26 AM
  • No te arroja el num maximo de tus cuotas porque estas agrupando sin relacionar esas cuotas con tu query externa.. es dificil seguir sin conocer tus estructuras y tus reglas..

    Ahora, sin conocer tu funcionamiento interno, me da la impresion que tienes que tener algun modo de relacionar las filas de tu subquery con la query externa, cosa que hasta ahora no estoy viendo que estes haciendo..

    Saturday, September 01, 2012 5:45 AM
  • Hola.

    Como ya te han comentado, es complicado si tenemos que hacer suposiciones. No nos dices qué quieres obtener. En cualquier caso, hago una sugerencia más.

    Tu sentencia inicial era esta:

    AND OAC.NumCuotaCalendario=
    	   (SELECT MAX(OAC1.NumCuotaCalendario)
    		FROM CONTABILIDAD1 C1
    	    INNER JOIN OPERACIONACTIVACALENDARIO OAC1
    	    ON  C1.CodOperacion=OAC1.CodOperacionActiva
    	    WHERE 1=1
    		AND OAC1.EstadoCuotaCalendario in ('C')
    		GROUP BY C1.CodOperacion,OAC1.CodOperacionActiva)

    Obtienes más de un resultado porque agrupas por CodOperacion y CodOperacionActiva (realmente valen lo mismo). Cambiarlo por un "IN" hace que no falle, pero sigues en las mismas, no obtienes lo que buscas. Creo que lo que tendrías que hacer es relacionarla con la tabla "Contabilidad". Sería más o menos así:

    SELECT OAC.NumCuotaCalendario,*
    FROM
      CONTABILIDAD C INNER JOIN 
      OPERACIONACTIVACALENDARIO OAC ON  C.CodOperacion=OAC.CodOperacionActiva INNER JOIN  
      CREDITORECUPERACION CR ON  C.CodOperacion=CR.CodOperacionActiva INNER JOIN  
      (
       SELECT OAC1.CodOperacionActiva, Max_NumCuotaCalendario = MAX(OAC1.NumCuotaCalendario)
       FROM 
        CONTABILIDAD C1 INNER JOIN 
        OPERACIONACTIVACALENDARIO OAC1 ON  C1.CodOperacion=OAC1.CodOperacionActiva 
       WHERE OAC1.EstadoCuotaCalendario IN ('C')
       GROUP BY OAC1.CodOperacionActiva
      ) MaxCuot
                ON C.CodOperacion = MaxCuot.CodOperacionActiva and OAC.NumCuotaCalendario = MaxCuot.Max_NumCuotaCalendario
    WHERE 
      OAC.EstadoCuotaCalendario IN ('C') AND 
      (Select FechaHoy From FechaCierre)>=OAC.FechaVencimientoCuota AND
      CR.EstadoRecuperacion='H'

    Si no fuera eso, apórtanos algún detalle más de lo que deberías obtener y tratamos de ayudarte.


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

    Saturday, September 01, 2012 9:12 AM
  • Hola qwalgrande gracias por tu respuesta.

     Me he dado cuenta que estaba empleando una mala logica para lo que tengo que hacer te lo voy a detallar mas ahora que lo tengo claro

    yo tengo que hacer update de la tabla contabilidad en el campo filler ,pero con las condiciones que puse arriba .

    Lo que debo lograr es actualizar la tabla contabilidad pero siempre y cuando el campo estadocuotacalendario de la tabla operacionactivacalendario  se encuentre en "c" o "g" pero de su máxima cuota del campo nrocuotas es decir si tengo un calendario de 5 cuotas  tengo que verificar que la 5 este en "C" Ó "G"  ,lo demas es hacer join con la tabla CREDITORECUPERACION simpelmnet para validar que, el campo estado recuperacion este en H,pero de esta tabla no recuerdo bien su esructura ademas es un join simple ,espero me puedas ayudar con lo otro,aqui pongo la estructura de tablas y algo de data

    CREATE TABLE [dbo].[contabilidad](
    	[codoperacion] [int] NULL,
    	[descripcion] [varchar](50) NULL,
    	[filler] [char](2) NULL
    ) ON [PRIMARY]
    GO
    CREATE TABLE [dbo].[OPERACIONACTIVACALENDARIO](
    	[codoperacionactiva] [int] NULL,
    	[numerocuota] [int] NULL,
    	[descripcion] [varchar](50) NULL,
    	[estadocuotacalendario] [char](1) NULL
    ) ON [PRIMARY]
    GO
    insert into contabilidad values (1, descripp1 ,NULL)
    insert into contabilidad values (2, desc2 ,NULL)
    insert into contabilidad values (3, desc3 ,NULL)
    insert into contabilidad values (4, desc4 ,NULL)
    insert into contabilidad values (5, desc5 ,NULL)
    insert into contabilidad values (6, desc6 ,NULL)
    insert into contabilidad values (7, desc7 ,NULL)
    insert into contabilidad values (8, desc8 ,NULL)
    insert into operacionactivacalendario values (1, 1 ,ddd ,C)
    insert into operacionactivacalendario values (1, 2 ,FFFF ,C)
    insert into operacionactivacalendario values (1, 3 ,DDD ,C)
    insert into operacionactivacalendario values (1, 4 ,FFF ,D)
    insert into operacionactivacalendario values (2, 1 ,FSS ,C)
    insert into operacionactivacalendario values (2, 2 ,ERE ,C)
    insert into operacionactivacalendario values (2, 3 ,FDG ,C)
    insert into operacionactivacalendario values (2, 4 ,DFA ,C)
    insert into operacionactivacalendario values (2, 5 ,AAA ,V)
    insert into operacionactivacalendario values (3, 1 ,SSS ,C)
    insert into operacionactivacalendario values (3, 2 ,WW ,C)
    insert into operacionactivacalendario values (3, 3 ,WW ,V)
    insert into operacionactivacalendario values (4, 1 ,AA ,C)
    insert into operacionactivacalendario values (4, 2 ,WWW ,C)
    insert into operacionactivacalendario values (5, 1 ,AAA ,C)
    insert into operacionactivacalendario values (5, 2 ,SSSS ,C)
    insert into operacionactivacalendario values (5, 3 ,ASA ,C)
    insert into operacionactivacalendario values (5, 4 ,AQ ,V)


    Espero haber sido claro y que me puedan ayudar.

    Saturday, September 01, 2012 4:34 PM
  • alguna idea?.

    cursores u otro.

    Saturday, September 01, 2012 5:41 PM
  • Hola qwalgrande gracias por tu respuesta.

     Me he dado cuenta que estaba empleando una mala logica para lo que tengo que hacer te lo voy a detallar mas ahora que lo tengo claro

    yo tengo que hacer update de la tabla contabilidad en el campo filler ,pero con las condiciones que puse arriba .

    Lo que debo lograr es actualizar la tabla contabilidad pero siempre y cuando el campo estadocuotacalendario de la tabla operacionactivacalendario  se encuentre en "c" o "g" pero de su máxima cuota del campo nrocuotas es decir si tengo un calendario de 5 cuotas  tengo que verificar que la 5 este en "C" Ó "G"  ,lo demas es hacer join con la tabla CREDITORECUPERACION simpelmnet para validar que, el campo estado recuperacion este en H,pero de esta tabla no recuerdo bien su esructura ademas es un join simple ,espero me puedas ayudar con lo otro,aqui pongo la estructura de tablas y algo de data

    CREATE TABLE [dbo].[contabilidad](
    	[codoperacion] [int] NULL,
    	[descripcion] [varchar](50) NULL,
    	[filler] [char](2) NULL
    ) ON [PRIMARY]
    GO
    CREATE TABLE [dbo].[OPERACIONACTIVACALENDARIO](
    	[codoperacionactiva] [int] NULL,
    	[numerocuota] [int] NULL,
    	[descripcion] [varchar](50) NULL,
    	[estadocuotacalendario] [char](1) NULL
    ) ON [PRIMARY]
    GO
    insert into contabilidad values (1, descripp1 ,NULL)
    insert into contabilidad values (2, desc2 ,NULL)
    insert into contabilidad values (3, desc3 ,NULL)
    insert into contabilidad values (4, desc4 ,NULL)
    insert into contabilidad values (5, desc5 ,NULL)
    insert into contabilidad values (6, desc6 ,NULL)
    insert into contabilidad values (7, desc7 ,NULL)
    insert into contabilidad values (8, desc8 ,NULL)
    insert into operacionactivacalendario values (1, 1 ,ddd ,C)
    insert into operacionactivacalendario values (1, 2 ,FFFF ,C)
    insert into operacionactivacalendario values (1, 3 ,DDD ,C)
    insert into operacionactivacalendario values (1, 4 ,FFF ,D)
    insert into operacionactivacalendario values (2, 1 ,FSS ,C)
    insert into operacionactivacalendario values (2, 2 ,ERE ,C)
    insert into operacionactivacalendario values (2, 3 ,FDG ,C)
    insert into operacionactivacalendario values (2, 4 ,DFA ,C)
    insert into operacionactivacalendario values (2, 5 ,AAA ,V)
    insert into operacionactivacalendario values (3, 1 ,SSS ,C)
    insert into operacionactivacalendario values (3, 2 ,WW ,C)
    insert into operacionactivacalendario values (3, 3 ,WW ,V)
    insert into operacionactivacalendario values (4, 1 ,AA ,C)
    insert into operacionactivacalendario values (4, 2 ,WWW ,C)
    insert into operacionactivacalendario values (5, 1 ,AAA ,C)
    insert into operacionactivacalendario values (5, 2 ,SSSS ,C)
    insert into operacionactivacalendario values (5, 3 ,ASA ,C)
    insert into operacionactivacalendario values (5, 4 ,AQ ,V)


    Espero haber sido claro y que me puedan ayudar.

    Para resolver esta parte:

    Lo que debo lograr es actualizar la tabla contabilidad pero siempre y cuando el campo estadocuotacalendario de la tabla operacionactivacalendario  se encuentre en "c" o "g" pero de su máxima cuota del campo nrocuotas es decir si tengo un calendario de 5 cuotas  tengo que verificar que la 5 este en "C" Ó "G"

    puedes usar el siguiente query, que te selecciona los registros de la tabla CONTABILIDAD cuyo registro correspondiente en OPERACIONACTIVACALENDARIO tiene la maxima cuota en en "C" o "G":

    SELECT * FROM CONTABILIDAD c
    WHERE c.codoperacion IN
    (
    	SELECT oac.codoperacionactiva 
    	FROM  OPERACIONACTIVACALENDARIO  oac
    	INNER JOIN 
    		(SELECT codoperacionactiva,MAX(numerocuota) AS maxcuota 
    		FROM OPERACIONACTIVACALENDARIO 
    		GROUP BY codoperacionactiva ) tbl
    		ON oac.codoperacionactiva = tbl.codoperacionactiva 
    			AND oac.numerocuota=tbl.maxcuota
    	WHERE estadocuotacalendario IN ('C','G')
    )

    A partir de aqui puedes hacer el join a la tercera tabla que mencionas y seleccionar el grupo final para el update.

    Saludos,

    Monica


    My Blog

    This posting is provided "AS IS" with no warranties, and confers no rights. Please remember to click "Mark as Answer" and "Vote as Helpful" on posts that help you. This can be beneficial to other community members reading the thread.

    • Marked as answer by Augusto C Saturday, September 01, 2012 7:14 PM
    • Unmarked as answer by Augusto C Thursday, September 27, 2012 10:58 PM
    Saturday, September 01, 2012 6:48 PM
  • Muchas gracias de moemnto veo que funciona ,

    yo abia intentado como tu pero no puse la condicion

    AND oac.numerocuota=tbl.maxcuota

    voy a hcver mis ruebas pero creo que eso lo resuelve gracias.


    Saturday, September 01, 2012 7:14 PM
  • le agradeco mucho la respuesta

    Monica Rivera

    pero me han dicho que el uso de subquerys es malisimo para el rendimiento que ni se donde medir

    en esta parte me dijeron que modifique

    SELECT * FROM CONTABILIDAD c
    WHERE c.codoperacion IN
    (
    SELECT oac.codoperacionactiva
    FROM  OPERACIONACTIVACALENDARIO  oac

    Thursday, September 27, 2012 10:59 PM
  • Hola.

    ¿Qué rendimiento tiene y qué rendimiento esperas? Emplear subconsultas no ha de ser algo negativo en sí mismo, estamos hablando de una cuestión compleja.


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

    Friday, October 12, 2012 2:36 PM
  • Este hilo está repetido. No lo fusiono porque el otro ya es bastante extenso de por sí, pero lo cierro para no mantener ambos. El otro hilo es el siguiente:

    http://social.technet.microsoft.com/Forums/es-ES/sqlserveres/thread/c37f3878-7c27-4b3e-b947-40a19eca271b


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

    Thursday, October 25, 2012 7:18 PM