sql - 来自group flag setter的max

时间:2012-10-20 00:18:30

标签: sql sql-server sql-server-2008 sql-server-2005

我正在尝试为下面的表格中的条件设置标志设置

p_id      mon_year      e_id     flag  
----      ---------     -----    -----
 1          2011/11       20       0
 1          2011/11       21       1
 1          2012/01       22       1
 1          2012/02       23       0
 1          2012/02       24       0
 1          2012/02       25       1
 2          2011/11       28       0
 2          2011/11       29       1
 2          2012/01       30       1

按p_id,e_id和mon_year分组,该标志设置为该月的最后一个值。

我很困惑,我怎么能实现这个

我试图通过使用row_number和partition来分离这个值来实现这一点。仍然在寻找实现

使用row_number查询输出,我得到如下:

分组

p_id      mon_year      e_id     row
----      ---------     -----    -----
 1          2011/11       20       1
 1          2011/11       21       2
 1          2012/01       22       1
 1          2012/02       23       1
 1          2012/02       24       2
 1          2012/02       25       3
 2          2011/11       28       1
 2          2011/11       29       2
 2          2012/01       30       1

此值的最大值将设置标志列。但我真的错过了如何实现它。任何帮助都会有用。

谢谢!

3 个答案:

答案 0 :(得分:0)

尝试降序排序。这样,你不必寻找最大的ROW_NUMBER但是当ROW_NUMBER是1时;)

这样的事情(我并不完全明白你想要达到的目标,所以这可能不是100%准确):

WITH r_MyTable
AS
(
    SELECT 
        *,
        ROW_NUMBER() OVER (PARTITION BY mon_year ORDER BY p_id, e_id DESC) AS GroupRank
    FROM MyTable
)
UPDATE r_MyTable
SET flag = CASE WHEN GroupRank = 1 THEN 1 ELSE 0 END;

答案 1 :(得分:0)

我认为这就是你想要的。 。 。输出完全符合您的示例:

declare @t table (p_id int, [year] int, [month] int,  [day] int)
insert @t select 1, 2011, 11, 20
    union select 1, 2011, 11, 21
    union select 1, 2012, 01, 22
    union select 1, 2012, 02, 23
    union select 1, 2012, 02, 24
    union select 1, 2012, 02, 25
    union select 2, 2011, 11, 28
    union select 2, 2011, 11, 29
    union select 2, 2012, 01, 30

select p_id, [year], [month], [day] 
, case when r=1 then 1 else 0 end flag
from
(
    select p_id, [year], [month], [day]
    , row_number() over (partition by p_id, [year], [month] order by [day] desc) r
    from @t
) x
order by  p_id, [year], [month], [day]

输出:

p_id    year    month   day     flag
1       2011    11      20      0
1       2011    11      21      1
1       2012    1       22      1
1       2012    2       23      0
1       2012    2       24      0
1       2012    2       25      1
2       2011    11      28      0
2       2011    11      29      1
2       2012    1       30      1

答案 2 :(得分:0)

您可以在e_id上​​使用max语句获取该月的最后一个值,代码如下:

    IF OBJECT_ID('tempdb..#tmptest') IS NOT NULL
        DROP TABLE #tmptest

    SELECT
        *
    INTO
        #tmptest
    FROM
    (
        SELECT  '1' p_id,          '2011/11' mon_year,       '20' e_id,      '0' flag UNION ALL
        SELECT  '1',          '2011/11',       '21',       '1' UNION ALL
        SELECT  '1',          '2012/01',       '22',       '1' UNION ALL
        SELECT  '1',          '2012/02',       '23',       '0' UNION ALL
        SELECT  '1',          '2012/02',       '24',       '0' UNION ALL
        SELECT  '1',          '2012/02',       '25',       '1' UNION ALL
        SELECT  '2',          '2011/11',       '28',       '0' UNION ALL
        SELECT  '2',          '2011/11',       '29',       '1' UNION ALL
        SELECT  '2', '2012/01',       '30',       '1' 
    ) as tmp

    SELECT
        tmptest.*
    FROM
        (
            SELECT 
                MAX(e_id) e_id
                ,p_id
                ,mon_year
            FROM 
                #tmptest
            GROUP BY
                p_id,mon_year
        ) tblLastValueEID
    INNER JOIN
        #tmptest tmptest
    ON
        tmptest.p_id = tblLastValueEID.p_id
    AND
        tmptest.mon_year = tblLastValueEID.mon_year
    AND
        tmptest.e_id = tblLastValueEID.e_id