簡體   English   中英

選擇一行具有不同的一列值

[英]Select one row with distinct value of one column

這是數據

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;

運行這個:

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;

由於多次返回相同的商家ID,因此不會返回所需的結果:

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

以下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順序解決“爭議”。

你喜歡這樣的東西可以工作:

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

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

根據您運行的sql類型(mysql,sql server等),將有替代答案。

例如,在sql server中,您可以說“為每個商家分配一個數字,從1開始”,並始終選擇數字1。

在通用sql中,你必須不那么直接。 您的ID列似乎是唯一的嗎? 如果是這樣,一種表達問題的方法是“獲取日期范圍內的記錄WHERE在相同商家的相同日期范圍內沒有更高的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)

所有這些其他答案看起來都非常復雜......您可以使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM