选择一行具有不同的一列值

BC *_*ats 5 sql oracle greatest-n-per-group

这是数据

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
Run Code Online (Sandbox Code Playgroud)

我需要按start_date(desc)排序所有行,其中start_date<=todayend_date >=today每个限制1 merchant_id.这意味着如果查询找到多个行,则只返回第一行.


测试脚本

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;
Run Code Online (Sandbox Code Playgroud)

运行这个:

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;
Run Code Online (Sandbox Code Playgroud)

由于多次返回相同的商家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
Run Code Online (Sandbox Code Playgroud)

Bra*_*vic 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
Run Code Online (Sandbox Code Playgroud)

本质上,它首先按日期过滤行,然后忽略除第一行之外共享相同 MERCHANT_ID 的所有行。

请注意,“第一个”的含义是相对于 START_DATE 降序定义的。如果两行具有相同的 START_DATE,则使用 ID 顺序解决“争议”。