我有一个表格,其中包含以下条目,并且在涉及日期时我正在努力进行分组。
id ref startDate
---- ----- -------------
1 001 01-01-2013
2 001 03-02-2013
3 002 31-01-2013
4 002 15-01-2013
5 001 05-06-2013 ....
我要做的是为每个参考选择前2个最大日期,以便我得到以下内容。
id ref startDate
---- ----- -------------
5 001 05-06-2013
2 001 03-02-2013
3 002 31-01-2013
4 002 15-01-2013
我认为这意味着要遵循......
SELECT *
FROM TABLE a
JOIN (SELECT startDate
FROM TABLE b
JOIN TABLE c
ON b.ref = c.ref AND b.startDate >= c.startDate
GROUP BY ref) AS d
ON a.ref = b.ref
我使用SQL 2000,所以不幸的是,分区是不可能的。
答案 0 :(得分:1)
只需放置此子句(根据您的需要进行修改)在查询的某处,它应该只为您提供特定参考的前两个StartDate。
WHERE b.StartDate IN
(SELECT TOP 2 StartDate FROM b WHERE a.ref = b.ref ORDER BY StartDate DESC)
由于您的JOIN
似乎是您最初尝试过滤的内容,请将您拥有的JOIN
替换为上面的WHERE
。确保您对其进行编辑,使其与您的实际表名相匹配
答案 1 :(得分:0)
以下是使用相关子查询的方法:
SELECT *
FROM TABLE t
WHERE (select count(*)
from Table t2
where t2.ref = t.ref and
t2.date >= t.date
) <= 2;
这假定日期在每个组中都是唯一的。
Here是一个SQL小提琴,显示它正常工作。
编辑:
如果日期不是唯一的,那么可以修改这个以获得前两个日期的顶行:
SELECT *
FROM TABLE t
WHERE (select count(distinct t2.date)
from Table t2
where t2.ref = t.ref and
t2.date >= t.date
) <= 2;
或者,它可以通过这种方式限制为两行:
SELECT *
FROM TABLE t
WHERE (select count(*)
from Table t2
where t2.ref = t.ref and
(t2.date > t.date or t2.date = t.date and t2.id <= t.id)
) <= 2;
答案 2 :(得分:0)
请检查
DECLARE @REF_TABLE AS TABLE(ID INT IDENTITY(1,1),REF VARCHAR(10))
DECLARE @LOOP_COUNT INT
DECLARE @ID INT=1
DECLARE @REF VARCHAR(10)
SELECT @LOOP_COUNT=COUNT(*) FROM @REF_TABLE
SELECT * INTO #TEMP FROM YOURTABLE WHERE 1=2
INSERT INTO @REF_TABLE SELECT DISTINCT REF FROM YOURTABLE
WHILE @LOOP_COUNT<@ID
BEGIN
SELECT @REF=REF FROM @REF_TABLE WHERE ID=@ID
INSERT INTO #TEMP SELECT TOP 2 * FROM YOURTABLE WHERE REF=@REF ORDER BY startDate DESC
SELECT @ID=@ID+1
END
SELECT * FROM #TEMP`
答案 3 :(得分:0)
我认为这可以满足您的需求(我知道它有点长,因为我们不能使用CTE或任何Windows功能)。
出于测试目的,我添加了一些额外的记录(same ref with duplicate startdate
和different refs with same startdate
),并进行了评论。
<强> Sql fiddle is here 强>
select min(id) id, t.ref, t.sdate
from t join (
select ref, max(sdate) as sdate
from t
group by ref
union
select t.ref, max(t.sdate) as sdate
from t join (
select ref, max(sdate) as sdate
from t
group by ref
) t2 on t.ref = t2.ref and t.sdate < t2.sdate
group by t.ref
) x on t.ref = x.ref and t.sdate = x.sdate
group by t.ref, t.sdate
order by t.ref, t.sdate desc