Group By和inner连接基于TimeStamp的最新记录

时间:2016-10-03 09:22:02

标签: sql-server

我有一个History表格如下:

ID | GroupCode | Category | TimeStamp
---+-----------+----------+-----------
1  | x         | shoes    | 2016-09-01
2  | y         | blach    | 2016-09-01

History表每月更新一次,每个GroupCode的一个条目都会插入表格中。

我还有一张Current表,其中包含最新的位置。

在我使用当前位置更新History表之前或之后,我想知道Category是否已从上个月更改为本月。

我需要将最后Category与当前Category进行比较,如果已更改,则在CategoryChanged表中标记Current

Current表:

ID | GroupCode | Category | CategoryChanged
---+-----------+----------+----------------
1  | x         | shoes    | True       
2  | y         | blah     | False

我尝试使用INNER JOIN实现此目的但我在INNER JOIN表格中遇到History最新月份和年份条目时遇到了困难,但没有成功。

2 个答案:

答案 0 :(得分:1)

--get highest group code based on timestamp   
 ;with History
    as
    (select top 1 with ties groupcode,category
    from
    history
    order by 
    row_number() over (partition by group code order by timestamp desc) as rownum
    )

--now do a left join with current table
    select 
    ct.ID,
    ct.GroupCode,
    ct.Category,
    case when ct.category=ht.category or ht.category is null then 'False'
         else 'true'
    end as 'changed'
     from
    currenttable ct
    left join
    history ht
    on ht.groupcode=ct.groupcode

在检查您的选择值是否正确后,请使用以下内容进行更新。

update ct
set ct.category=
 case when ct.category=ht.category or ht.category is null then 'False'
             else 'true'
        end 
         from
        currenttable ct
        left join
        history ht
        on ht.groupcode=ct.groupcode

答案 1 :(得分:0)

如果你制作一个CTE,其中历史记录的每个GroupCode的rown_numbwer按日期降序排序,那么你对第1行和第2行感兴趣,那么你可以将你的CTE加入GroupCode,然后选择记录1和2,你可以查看类别是否在第1行和第2行之间发生了变化

    ;WITH CTE AS (SELECT *, row_number() OVER (PARTITION BY GroupCode ORDER BY TimeStamp Desc) RN FROM History)
    SELECT 
            C1.ID, 
            C1.GroupCode, 
            C1.Category, 
            CASE WHEN C1.Category = C2.Category THEN 
                'false' 
            else 
                'true' 
            end AS CategoryChanged

                FROM CTE C1 
                        JOIN 
                            CTE C2 
                                ON C1.GroupCode = C2.GroupCode 
                                    AND C1.Rn=1 AND C2.RN = 2;

如果你有空类别,你可以避免 - BTW你需要学习如何处理NULL你想要处理它们的方式 - 你不能指望人们在这里发帖思考你从未提到过的NULL永远!并且正在实现你想要对他们做什么

;WITH CTE AS (SELECT *, row_number() OVER (PARTITION BY GroupCode ORDER BY TimeStamp Desc) RN FROM History)
    SELECT 
            C1.ID, 
            C1.GroupCode, 
            C1.Category, 
            CASE WHEN C1.Category = C2.Category OR C1.Category IS NULL AND C2.Category IS NULL THEN 
                'false' 
            else 
                'true' 
            end AS CategoryChanged

                FROM CTE C1 
                        JOIN 
                            CTE C2 
                                ON C1.GroupCode = C2.GroupCode 
                                    AND C1.Rn=1 AND C2.RN = 2;