寻找最古老的最近访问。 (最小值按最大值分组)

时间:2017-12-14 15:33:45

标签: sql sql-server

我试图在列表中找到最早的日期,但我只想考虑每个可能的最新条目" person"。

即。考虑以下数据集(日期是varchar 103,即dd / mm / yyyy)

+--------+------+------------+
| Person | Shop | Date       |
+--------+------+------------+
| A      | X    | 09/01/2017 |
+--------+------+------------+
| A      | X    | 12/01/2017 |
+--------+------+------------+
| A      | Y    | 12/01/2017 |
+--------+------+------------+
| B      | X    | 01/01/2017 |
+--------+------+------------+
| B      | X    | 13/01/2017 |
+--------+------+------------+
| B      | Y    | 11/01/2017 |
+--------+------+------------+
| C      | X    | 14/01/2017 |
+--------+------+------------+
| C      | Y    | 18/01/2017 |
+--------+------+------------+
| C      | Y    | 07/01/2017 |
+--------+------+------------+

如果我想找到每个"商店"的最低日期使用情况。 (即MIN(DATE)GROUP BY Shop),然后我会在01年1月1日到01号商店获得Y.但是,在这两次访问中,访问过的人都来到了商店。以后的日期,所以我不想将这些日期视为最近最早的日期和#34;访问。

很明显,我想知道每个客户最近的访问,其中哪一个是最老的。也就是说,有人去过商店的最后日期是什么时候才回来。

我是否需要通过一个临时表格,我可以通过商店提取MAX(日期)组,或者是否有办法获取日期12/01/2017的X和11/01/2017的Y直接这个数据集?

我想要以下结果

+------+------------+
| Shop | Date       |
+------+------------+
| X    | 12/01/2017 |
+------+------------+
| Y    | 11/01/2017 |
+------+------------+

非常感谢任何帮助

2 个答案:

答案 0 :(得分:4)

最简单的方法是使用排名函数ROW_NUMBER

with cte as
(
   select Person, Shop, [Date],
          rn = ROW_NUMBER() OVER (PARTITION BY Person Order By CONVERT(datetime, t.[Date], 103) DESC)
   fromk dbo.TableName t
)
select Person, Shop, [Date]
from cte
where rn = 1

为什么不将日期存储为date / datetime,而是varchar

答案 1 :(得分:4)

您也可以在选择内部尝试选择:

CREATE TABLE #VISIT (Person CHAR(1), Shop CHAR(1), [Date] DATE)

INSERT INTO  #VISIT
SELECT 'A','X','09/01/2017'
UNION ALL SELECT 'A','X','01/12/2017'
UNION ALL SELECT 'A','Y','01/12/2017'
UNION ALL SELECT 'B','X','01/01/2017'
UNION ALL SELECT 'B','X','01/13/2017'
UNION ALL SELECT 'B','Y','01/11/2017'
UNION ALL SELECT 'C','X','01/14/2017'
UNION ALL SELECT 'C','Y','01/18/2017'
UNION ALL SELECT 'C','Y','01/07/2017'

SELECT minDate.Shop
    ,Min(minDate.lastVisit)
FROM (
    SELECT Person
        ,Shop
        ,Max([Date]) lastVisit
    FROM #VISIT
    GROUP BY Person
        ,Shop
    ) AS minDate
GROUP BY minDate.Shop