2011-11-25 60 views
5

這種鮮明的價值一行是數據選擇與一列

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 

我需要通過start_date(DESC)排序的所有行start_date<=todayend_date >=today但每merchant_id限1。這意味着如果查詢發現多於一行,則返回第一個。


測試腳本

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; 

運行以下命令:

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 

爲同一商家ID多次返回
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; 

不返回預期的結果

+0

可以使用BETWEEN子句來代替起始日期<=今天日期和結束日期> =今天。 –

+0

我一直在嘗試各種不同的聲明,不同的,限制,組.. ..但一直沒能得到任何工作。我可以得到具有適當的開始和結束日期的所有行,但不知道如何返回1行每merchant_id –

+0

您使用哪個數據庫?如果您使用的是Oracle一個解決方案是使用分析功能 – Giovanni

回答

2

以下Oracle查詢應該做你需要的東西:

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 

實質上,它首先按日期過濾行,然後忽略除共享相同MERCHANT_ID的第一個之外的所有行。

請注意,「first」的含義是根據降序START_DATE順序定義的。它的兩行具有相同的START_DATE,則使用ID順序解決「爭議」。

+0

完美!謝謝! –

0

嗨這樣的事情可以工作:

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 

如果用於創建和填充表,我可以給你正確的查詢提供了一個簡單的測試腳本。

+0

將測試腳本添加到原始文章中。 –

0

根據你正在運行的SQL類型(mysql,sql server等),會有替代答案。

例如,在SQL Server,你可以說「分配各行的數量,從1開始的每個商家」,並總是挑號碼1.

在通用的SQL,你必須要少一點直接。它看起來你的ID列保證是唯一的?如果是這樣,問題的一種表達方式是「在日期範圍內獲取記錄,在同一商家的同一日期範圍內沒有更高的ID」

您是否已經知道如何過濾>和<?我想答案要怎麼做特定於你使用什麼類型的SQL:

所以嘗試:

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

SQL是針對Oracle的。 –

-1

所有這些其他答案看起來都很複雜......您可以使用Oracle中的DISTINCT修飾符爲每個特定列獲取一個且唯一一個唯一行。這裏是你可以用它來獲取你想要的數據的查詢,因爲在您的文章表結構:

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

這不會返回所需的結果 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; –

+0

不會爲單個列返回不同的行 – Sasi