2012-09-19 22 views
5

tengo esta tabla sql y filas definen en SQL FiddleSeleccione uno de la fila con la condición

En SUPPLIER_DETAILS mesa hay un campo llamado IS_PAYABLE que tendrá valores NULL o 'Y'.

Si IS_PAYABLE='Y', puede haber uno o más registros para cada PRODUCT_REG con diferentes PRODUCT_NO. P. ej. PRODUCT_REG = 'HP_C20' tiene dos registros con IS_PAYABLE='Y'.

HP_C20 FR-A GB-A128  Y 
HP_C20 FR-A GB-A098  Y 

Lo que me gustaría tener es si IS_PAYABLE='Y' y si hay varios registros para una PRODUCT_REG, entonces me gustaría que sea solamente uno de los registros y quiero que todos los registros con IS_PAYABLE is null.

¿Cómo puedo lograrlo? Si no hice comprensible mi requerimiento, lo explicaré más a fondo.

Cualquier ayuda es altamente apreciable.

Gracias

Respuesta

5
select * from 
    (select a.*, 
     row_number() over (partition by product_reg order by product_no) as rnk 
    from SUPPLIER_DETAILS a 
    order by PRODUCT_REG) 
where is_payable is null or rnk = 1; 

SQLFIDDLE

En consulta interna que he clasificados en los productos con el mismo product_reg.

En la consulta externa tengo solo un producto por producto_reg (el primero clasificado) y todos los productos no pagaderos.

+0

+1 Fiddle está funcionando, pero aquí se olvidó de alias. –

+0

@ NikolaMarkovinović gracias, lo he corregido. –

+0

@FlorinGhita Muchas gracias, esto funcionó como un encanto. Si encuentro algún problema con los registros, volveré con usted. Muy apreciado. – user75ponic

3

Prueba esto:

SELECT s.* 
FROM supplier_details s 
WHERE NOT EXISTS(SELECT s1.* 
        FROM supplier_details s1 
        WHERE s.is_payable = 'Y' 
         AND s1.is_payable = 'Y' 
         AND s.product_reg = s1.product_reg 
         AND s.product_no < s1.product_no) 
UNION 
SELECT * 
FROM supplier_details 
WHERE is_payable IS NULL 

http://sqlfiddle.com/#!4/25c52/2/0

EDIT: por debajo de código también debería funcionar (unión es redundante)

SELECT s.* 
FROM supplier_details s 
WHERE NOT EXISTS(SELECT s1.* 
        FROM supplier_details s1 
        WHERE s.is_payable = 'Y' 
         AND s1.is_payable = 'Y' 
         AND s.product_reg = s1.product_reg 
         AND s.product_no < s1.product_no) 

http://sqlfiddle.com/#!4/5e69b/1/0

+0

Gracias por su respuesta. – user75ponic

3

En esta situación row_number() la función analítica será útil.

select product_reg 
     , product_supplier_code 
     , product_no 
     , is_payable 
    from (select t.* 
       , row_number() over (partition by product_reg order by product_no) m 
      from SUPPLIER_DETAILS t 
     ) 
    where m = 1 
     or is_payable is null 
    order by product_reg 

Demo#1

Además

parece ser un duplicado.Para distinguir la respuesta un poco aquí es otro método que puede utilizar para obtener el resultado deseado

select product_reg 
    , max(PRODUCT_SUPPLIER_CODE) KEEP (DENSE_RANK FIRST ORDER BY product_reg) PRODUCT_SUPPLIER_CODE 
    , max(PRODUCT_NO) KEEP (DENSE_RANK FIRST ORDER BY product_reg) PRODUCT_NO 
    , max(IS_PAYABLE) KEEP (DENSE_RANK FIRST ORDER BY product_reg) IS_PAYABLE 
from SUPPLIER_DETAILS t 
group by product_reg 
order by product_reg 

Demo#2

+0

Gracias por su respuesta. – user75ponic

2

Puede utilizar UNION ALL para esto, pero al volver los registros where IS_PAYABLE = 'Y' utilizar un agregado de retorno siempre el valor MAX() o MIN()

select PRODUCT_REG, PRODUCT_SUPPLIER_CODE, max(PRODUCT_NO) PRODUCT_NO, IS_PAYABLE 
from SUPPLIER_DETAILS 
where IS_PAYABLE = 'Y' 
group by PRODUCT_REG, PRODUCT_SUPPLIER_CODE, IS_PAYABLE 
union all 
select PRODUCT_REG, PRODUCT_SUPPLIER_CODE, PRODUCT_NO, IS_PAYABLE 
from SUPPLIER_DETAILS 
where IS_PAYABLE is null 
order by PRODUCT_REG 

Ver SQL Fiddle with Demo

+0

Gracias por su respuesta. – user75ponic

Cuestiones relacionadas