none
COMO USAR UN ARRAY O LISTA EN LA CLAUSULA WHERE? RRS feed

  • Pregunta

  • Digamos que necesito evaluar mediante WHERE  10 valores de un mismo campo, para obtener 10 registros que cumplen con un criterio simple NOFACTURA

    Normalmente es:

    SELECT NOFACTURA FROM TBLFACTURAS WHERE NOFACTURA=....(AQUI LOS DIEZ NUMEROS DE FACTURA)

    ¿ES POSIBLE EVITAR REPETIR 10 VECES: NOFACTURA=1 OR NOFACTURA=2.......HASTA N FACTURAS?

    EXISTE EN SQL ALGUN ARRAY COMO:   WHERE NOFACTURA={1,2,3,4,5,6,7,8,9,10}   ???

    Gracias de antemano


    Luis C

    martes, 11 de agosto de 2020 17:21

Respuestas

Todas las respuestas

  • ya encontré la respuesta, en  el sig. Link

    https://stackoverflow.com/questions/13424796/sql-possible-to-use-input-array-in-where-clause

    La solución esta en usar IN

    SELECT col1, col2, ..., coln
    FROM tabla
    WHERE Campo IN ('input_1', 'input_2', 'input_3')


    Luis C

    martes, 11 de agosto de 2020 17:34
  • Hola Luis Carlos H:

    Aunque ya has encontrado una solución a tú pregunta, realmente es muy interesante, porque existen múltiples maneras de conseguir el mismo objetivo.

    Tal cual planteas el escenario:

    Create table ejFacturas
     (
     id        int identity(1, 1) primary key
      , NoFactura varchar(10)
      , valor     int
     );
    GO
    
    Insert into ejFacturas (NoFactura, valor)
    values
    ('input_1' ,50),
    ('input_2' ,25),
    ('input_3' ,20),
    ('input_4' ,50),
    ('input_5' ,30),
    ('input_6' ,40),
    ('input_7' ,60),
    ('input_8' ,20),
    ('input_9' ,10),
    ('input_10',70),
    ('input_11',80),
    ('input_12',90),
    ('input_13',20),
    ('input_14',30);
    GO

    Opción 1: La que ya has mostrado con IN

    SELECT * 
    	FROM dbo.ejFacturas
    	WHERE NoFactura in ('input_1','input_2','input_3');


    Opción 2: Utilizar un Constructor con valores de tabla (Tvc)

    SELECT F.*
    	FROM dbo.ejFacturas F INNER JOIN
    		( SELECT T.nroFactura  
    			FROM (VALUES ('input_4'),('input_5'),('input_6')) T(nroFactura)
    		) AS Tvc
    		ON Tvc.nroFactura = F.NoFactura;

    Esta tiene la ventaja, de que se podrían aplicar patrones de búsqueda no exactos, porque la relación entre F.NoFactura podría ser con like Tvc.NroFactura +'%' o algo del estilo.

    Opción 3: Utilizar Union

    SELECT F.* 
    	FROM dbo.ejFacturas F
    		INNER JOIN (
    			SELECT 'input_7' AS INPUT
    			UNION ALL 
    			SELECT 'input_8'
    			UNION ALL 
    			SELECT 'input_9'
    		) Inp on f.NoFactura = Inp.INPUT;

    Construyes la lista de valores, y relacionas estos con la tabla por la columna.

    Opción 4: Operador Exists

    SELECT Factura.* 
    	FROM dbo.ejFacturas Factura
    	WHERE 
    		EXISTS 
    		(
    		 SELECT T.nroFactura  
    		 FROM (VALUES ('input_10'),('input_11'),('input_12')) T(nroFactura)
    		 WHERE T.nroFactura = Factura.NoFactura
    		 );

    Opción 5: Utilizar la búsqueda sobre una cadena y con un separador String split  (Sql 2016 o sup).

     Select * from dbo.ejFacturas f
    	WHERE F.NoFactura IN ( 
    		SELECT VALUE FROM string_split('input_3,input_5,input_9',','))

    Existen más opciones, seguro, pero estas al menos dan una muestra de lo rico que puede ser el lenguaje TSQL.

    Tvc

    https://javifer2.wordpress.com/2020/04/05/arrays-en-sql-server-constructor-con-valores-de-tabla/

    Union

    https://javifer2.wordpress.com/2020/04/07/union-vs-union-all/

    Exists

    https://javifer2.wordpress.com/2020/06/17/exists-como-se-implementa/

    String split

    https://javifer2.wordpress.com/2019/10/27/string-split-separar-cadenas/

    miércoles, 12 de agosto de 2020 4:33
  • Gracias Luis Carlos, por compartir tu respuesta, si tienes otra duda, levanta un hilo en MSDN.

    Saludos

    miércoles, 12 de agosto de 2020 13:27
    Moderador