2013-02-28 33 views
2

我有一张表格,每月填充大量交易,如下所示。根据日期创建具有不同值的表格

Name   ID  Date   OtherColumn 
_________________________________________________ 
John Smith 11111  2012-11-29 Somevalue 
John Smith 11111  2012-11-30 Somevalue 
Adam Gray  22222  2012-12-11 Somevalue 
Tim Blue  33333  2012-12-15 Somevalue 
John NewName 11111  2013-01-01 Somevalue 
Adam Gray  22222  2013-01-02 Somevalue 

从这张表我想创建一个唯一的名称和ID的维度表。问题在于一个人可以改变他/她的名字,例如上面的例子中的“约翰”。 Id的其他地方总是独一无二的。在这些情况下,我只想使用最新的名称(最新的日期)。

这样我结束了像这样的表:

Name   ID 
______________________ 
John NewName 11111 
Adam Gray  22222 
Tim Blue  33333 

我如何去实现呢?
我可以在单个查询中完成吗?

+0

John Smith和John NewName是同一个人吗?你想保留包括约翰史密斯在内的所有用户名为'11111'的历史记录,还是只需要John NewName? – kush 2013-02-28 13:41:28

+1

@ kush他很清楚地说他想要每个ID值的最新名字 – JNK 2013-02-28 13:43:15

+0

Sporki,我怎么知道“John NewName”比“John Smith”更新?是否因为“John NewName”是您展示的顶级表中ID = 11111的最新条目? – deblendewim 2013-02-28 13:44:29

回答

2

为此使用CTE。它简化了排名和窗口功能。

;WITH CTE as 
(SELECT 
    RN = ROW_NUMBER() OVER (PARTITION BY ID ORDER BY [Date] DESC), 
    ID, 
    Name 
FROM 
    YourTable) 
SELECT 
    Name, 
    ID 
FROM 
    CTE 
WHERE 
    RN = 1 
+0

CTE应该没有“FROM”部分吗? – whytheq 2013-02-28 14:17:28

+1

@whytheq它绝对应该!固定。 – JNK 2013-02-28 14:36:25

+0

这就像一个魅力!谢谢! – Sporki 2013-02-28 14:41:26

1

我认为创建表是一个坏主意,但这是如何获得最近的名称。

select name 
from yourtable yt join 
(select id, max(date) maxdate 
from yourtable 
group by id) temp on temp.id = yt.id and yt.date = maxdate 
+0

......如果他在同一天有两个相同名字的值,那么这将会造成一些困惑。 – JNK 2013-02-28 13:47:19

+0

为什么这是一个坏主意?我认为你的解决方案是一个好方法。它只是在select子句中缺少'ID'。 – Hudon 2013-02-28 13:47:42

+0

@JNK,难道他不能只从''选择名称,DISTINCT(ID)吗? – Hudon 2013-02-28 13:48:38

0

JNK的CTE解决方案相当于以下内容。

SELECT 
    Name, 
    ID 
FROM (
    SELECT 
     RN = ROW_NUMBER() OVER (PARTITION BY ID ORDER BY [Date] DESC), 
     Name, 
     ID 
    FROM theTable 
    ) 
WHERE RN = 1 

试图想办法摆脱分区功能,而不会引入可能的重复。

相关问题