以下简单查询将返回结果,其中包含按日期排序的名称和日期。
SELECT DISTINCT Name, Date
FROM dbo.Table WITH(NOLOCK)
ORDER BY DATE
结果
Name | Date
--------------------
a | 31-Jul-2013
a | 31-Aug-2013
a | 30-Sep-2013
b | 31-Oct-2013
b | 30-Nov-2013
a | 31-Dec-2013
我如何只选择不同的名称,但名称的顺序必须按日期排序?
新结果
Name
a
b
a
答案 0 :(得分:2)
尝试此查询:
WITH Names AS (
SELECT
Name,
Seq = Dense_Rank() OVER (ORDER BY SomeDate)
- Dense_Rank() OVER (PARTITION BY Name ORDER BY SomeDate)
FROM
dbo.Names
)
SELECT Name
FROM Names
GROUP BY Name, Seq
ORDER BY Min(Seq)
;
<强> Run this live in a SQL Fiddle 强>
这将返回您请求的A,B,A模式。
您无法使用简单的DISTINCT,因为您要求显示单个值,而是按所有排序该值可能与之关联的日期。如果您的数据看起来像这样怎么办?
Name Date
---- ----
A 2014-01-01
B 2014-02-01
B 2014-03-01
A 2014-04-01
如何根据日期的某个理论排序决定是先将A放在第一位,还是以B为先?
这就是为什么我不得不做上面的窗口函数减法,它应该按你想要的顺序排列。
备注强>
我将此技术称为&#34;模拟PREORDER BY&#34;。 Dense_Rank
在排序之前没有提供任何预先排序行的方法。如果您可以Dense_Rank() OVER (PREORDER BY Date ORDER BY Name)
表示您希望首先按Date
订购,但又不希望它成为结果排名计算的一部分,那么您将被设置!但是,这并不存在。经过一段时间的研究后,我想到了使用窗口函数组合来实现目的的想法,上面的查询代表了结果。
请注意,您还必须<{em> GROUP BY
Name
,而不仅仅是生成的减去窗口表达式,以便一切正常工作,因为表达式是唯一的另一列(在本例中为Name
)可能导致整个集合中出现重复值(两个不同的值Names可以具有相同的表达式结果)。如果需要可以单独订购的值,您可以指定新的排名或其他窗口函数。
答案 1 :(得分:0)
我认为公用表表达式(CTE)可以在这里工作:
with cte as(
SELECT DISTINCT Name, Date
FROM dbo.Table WITH(NOLOCK)
ORDER BY DATE
)
select Name
from cte
order by Date