2011-11-25 13 views
5

Estos son los datosSeleccione una fila con valor distinto de una columna

id name  start_date end_date merchant_id 
=================================================== 
111 name1 25-nov-11 31-jan-12 9999 
222 name2 23-nov-11 25-dec-11 9999 
333 name3 25-nov-11 25-nov-12 9999 
444 name4 20-nov-11 20-nov-11 9999 
555 name5 25-nov-11 25-dec-11 8888 
666 name6 19-oct-11 20-nov-11 8888 
777 name7 20-nov-11 20-jun-12 8888 

que necesito para obtener todos los registros ordenados por start_date (desc) donde start_date<=today y end_date >=today pero límite de 1 por merchant_id. Lo que significa que si la consulta encuentra más de una fila, simplemente devuelva la primera.


script de prueba

CREATE TABLE DEAL 
(
    ID   VARCHAR2(40 BYTE)  NOT NULL, 
    NAME   VARCHAR2(255 BYTE), 
    START_DATE DATE, 
    END_DATE  DATE, 
    MERCHANT_ID NUMBER(22), 
CONSTRAINT DEAL PRIMARY KEY (ID) 
); 

INSERT ALL 
INTO DEAL (ID,NAME,START_DATE,END_DATE,MERCHANT_ID) VALUES ('111','name1','25-nov-11','31-jan-12','9999') 
INTO DEAL (ID,NAME,START_DATE,END_DATE,MERCHANT_ID) VALUES ('222','name2','23-nov-11','25-dec-11','9999') 
INTO DEAL (ID,NAME,START_DATE,END_DATE,MERCHANT_ID) VALUES ('333','name3','25-nov-11','25-nov-12','9999') 
INTO DEAL (ID,NAME,START_DATE,END_DATE,MERCHANT_ID) VALUES ('444','name4','20-nov-11','20-nov-11','9999') 
INTO DEAL (ID,NAME,START_DATE,END_DATE,MERCHANT_ID) VALUES ('555','name5','25-nov-11','25-dec-11','8888') 
INTO DEAL (ID,NAME,START_DATE,END_DATE,MERCHANT_ID) VALUES ('666','name6','19-oct-11','20-nov-11','8888') 
INTO DEAL (ID,NAME,START_DATE,END_DATE,MERCHANT_ID) VALUES ('777','name7','20-nov-11','20-jun-12','8888') 
SELECT * FROM dual; 

ejecutar este:

SELECT DISTINCT merchant_id, id, name, start_date, end_date FROM deal WHERE start_date <= trunc(sysdate) AND end_date >= trunc(sysdate) ORDER BY start_date DESC; 

no devuelve el resultado deseado como el mismo ID del vendedor se volvió varias veces:

MERCHANT_ID ID NAME START_DATE END_DATE 
=========================================== 
9999   111 name1 25-NOV-11 31-JAN-12 
9999   333 name3 25-NOV-11 25-NOV-12 
8888   555 name5 25-NOV-11 25-DEC-11 
9999   222 name2 23-NOV-11 25-DEC-11 
8888   777 name7 20-NOV-11 20-JUN-12 
+0

se puede utilizar en lugar de la cláusula ENTRE fecha_inicial <= hoy y fecha_final> = hoy. –

+0

He estado intentando varias declaraciones con distinct, limit, group by ... pero no he podido hacer que funcionen. Puedo obtener todas las filas con la fecha de inicio y finalización adecuada, pero no sé cómo devolver una fila por id_merchant –

+0

¿Qué base de datos está utilizando? Si está utilizando Oracle, una solución es utilizar las funciones analíticas – Giovanni

Respuesta

2

La siguiente consulta de Oracle debe hacer lo que necesita:

SELECT * 
FROM (
    SELECT TABLE1.*, DENSE_RANK() OVER(PARTITION BY MERCHANT_ID ORDER BY START_DATE DESC, ID) R 
    FROM TABLE1 
    WHERE SYSDATE BETWEEN START_DATE AND END_DATE 
) 
WHERE R = 1 
ORDER BY START_DATE DESC 

Esencialmente, primero filtra las filas por fecha y luego ignora todas las filas, pero primero que comparte el mismo MERCHANT_ID.

Tenga en cuenta que el significado de "primero" se define en relación con el orden START_DATE descendente. Las dos filas tienen el mismo START_DATE, luego la "disputa" se resuelve utilizando el orden de ID.

+0

¡Perfecto! ¡Gracias! –

0

Hola algo como esto podría funcionar:

select id, name,  start_date, end_date from (
select id, name,  start_date, end_date, ROW_NUMBER() 
    OVER (PARTITION BY merchant_id ORDER BY merchant_id) AS rnum from your_table 
    where start_date<=trunc(sysdate) and end_date>=trunc(sysdate)) 
    where rnum=1 
order by start_date desc 

si proporciona un script de prueba sencilla para crear y llenar la tabla que puedo darle la consulta correcta.

+0

Script de prueba agregado a la publicación original. –

0

Según el tipo de sql que esté ejecutando (servidor mysql, sql, etc.) habrá respuestas alternativas.

Por ejemplo, en el servidor SQL que se podría decir "Asignar cada fila un número, a partir de 1 de cada comerciante", y siempre elegir el número 1.

en SQL genérico, usted tiene que ser un poco menos directa . ¿Parece que su columna de id. Garantiza ser única? Si es así, una forma de redactar la pregunta es "obtener registros dentro del rango de fechas DONDE no hay una identificación más alta en el mismo rango de fechas para el mismo comerciante"

¿Ya sabe cómo filtrar por> y < hoy? Creo que la respuesta a cómo hacer que es específica para el tipo de SQL que está utilizando:

Así que trate de:

SELECT * from myFavoriteTable 
    WHERE today() < end_date and today > start_date -- for this date criteria use whatever works 
    AND NOT EXISTS (SELECT * from myFavoriteTable as TooLow 
     WHERE today() < end_date and today() > start_date -- as above 
     AND TooLow.Merchant = myFavoriteTable.merchant 
     AND TooLow.id > myFavoriteTable.id) 
+0

El SQL es para Oracle. –

-1

Todas estas otras respuestas parecen más complicadas ... Puede usar el modificador DISTINCT en Oracle para obtener una y única fila única por columna específica. Aquí es una consulta que se puede usar para recuperar los datos que desea, dada la estructura de la tabla en su mensaje:

SELECT DISTINCT merchant_id, id, name, start_date, end_date FROM table WHERE start_date >= today AND end_date < today ORDER BY start_date DESC

+0

Esto no devuelve los resultados requeridos SELECT DISTINCT id_comercio, id, nombre, fecha_inicial, fecha_final FROM transacción WHERE fecha_inicio <= trunc (fecha_sistema) Y fecha_final> = trunc (fecha_sistema) ORDEN POR fecha_inicio DESC; –

+0

No devuelve filas distintas para una sola columna – Sasi

Cuestiones relacionadas