简体   繁体   中英

select distinct of a column and order by date column but without showing the date column

The following simple query will return result with name and date which is order by date.

SELECT  DISTINCT Name, Date
FROM    dbo.Table WITH(NOLOCK)
ORDER BY DATE

Result

 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  

How can i select distinct only the Name but the sequence of the Name must be order by date?

New result

 Name  
  a  
  b  
  a

Try this query:

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

This will return the A, B, A pattern you requested.

You can't use a simple DISTINCT because you're asking to display a single value, but order by all the dates that the value may have associated with it. What if your data looks like this?

Name  Date
----  ----
A     2014-01-01
B     2014-02-01
B     2014-03-01
A     2014-04-01

How do you decide whether to put A first, or B first, based one some theoretical ordering by the date?

That is why I had to do the above subtraction of windowing functions, which should order things how you want.

Notes

I call this technique a "simulated PREORDER BY". Dense_Rank does not offer any way to preorder the rows before ranking based on ordering. If you could do Dense_Rank() OVER (PREORDER BY Date ORDER BY Name) to indicate that you want to order by Date first, but don't want it to be part of the resulting rank calculation, you'd be set! However, that doesn't exist. After some study a while back I hit on the idea to use a combination of windowing functions to accomplish the purpose, and the above query represents that result.

Note that you must also GROUP BY the Name , not just the resulting subtracted windowing expressions, in order for everything to work correctly, because the expression, while unique to the other column (in this case, Name ), can result in duplicate values across the entire set (two different value Names can have the same expression result). You can assign a new rank or other windowing function if there is a desire for a value that can be ordered by individually.

I think a common table expression (CTE) will work here:

with cte as(
SELECT  DISTINCT Name, Date
FROM    dbo.Table WITH(NOLOCK)
ORDER BY DATE
)
select Name 
from cte 
order by Date

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM