[英]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<=today
和end_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.