【问题标题】:Access query counter per group每组访问查询计数器
【发布时间】:2021-12-31 06:39:30
【问题描述】:

是否可以在 Access Query 中添加按组排序(排序/组)字段以按照下表按值排序:

注意: ID 是唯一索引(自动编号)

【问题讨论】:

    标签: sql ms-access


    【解决方案1】:

    在真正的 RDBMS 上,通常会为此使用窗口函数 ROW_NUMBER

    select *
    , row_number() over (partition by Group1 order by Value, ID) as Rownum
    from yourtable
    

    但另一种方法是使用相关子查询。

    select *, 
    (select count(*) from yourtable t2 
     where t2.Group1 = t.Group1
       and (t2.Value < t.Value
            or (t2.Value = t.Value and t2.ID <= t.ID)) ) as Rownum
    from yourtable t
    

    额外:

    显示ROW_NUMBERRANKDENSE_RANK 之间区别的简单测试

    create table yourtable (
     ID int identity(1,1) primary key, 
     Group1 int, 
     Value int
    );
    
    insert into yourtable (Group1, Value) values
      (10,100),(10,150),(10,150),(10,150),(10,360)
    , (200,360),(200,420),(200,420),(200,500),(200,500)
    
    --
    -- ROW_NUMBER (to get a sequence per group) 
    --
    select *
    , ROW_NUMBER() OVER (PARTITION BY Group1 ORDER BY Value, ID) as Rownum
    from yourtable
    order by Group1, Rownum
    
    身份证 |组1 |价值 |朗姆 -: | -----: | ----: | -----: 1 | 10 | 100 | 1 2 | 10 | 150 | 2 3 | 10 | 150 | 3 4 | 10 | 150 | 4 5 | 10 | 360 | 5 6 | 200 | 360 | 1 7 | 200 | 420 | 2 8 | 200 | 420 | 3 9 | 200 | 500 | 4 10 | 200 | 500 | 5
    --
    -- Emulating ROW_NUMBER via a correlated sub-query
    --
    select *, 
    (select count(*) from yourtable t2 
     where t2.Group1 = t.Group1
       and (t2.Value < t.Value 
            or (t2.Value = t.Value 
                and t2.ID <= t.ID))
    ) as Rownum
    from yourtable t
    order by Group1, Rownum
    
    身份证 |组1 |价值 |朗姆 -: | -----: | ----: | -----: 1 | 10 | 100 | 1 2 | 10 | 150 | 2 3 | 10 | 150 | 3 4 | 10 | 150 | 4 5 | 10 | 360 | 5 6 | 200 | 360 | 1 7 | 200 | 420 | 2 8 | 200 | 420 | 3 9 | 200 | 500 | 4 10 | 200 | 500 | 5
    --
    -- RANK (same values get same rank, but with gaps)
    --
    select *
    , RANK() over (partition by Group1 order by Value) as Ranknum
    from yourtable
    order by Group1, Ranknum
    
    身份证 |组1 |价值 |秩数 -: | -----: | ----: | ------: 1 | 10 | 100 | 1 2 | 10 | 150 | 2 3 | 10 | 150 | 2 4 | 10 | 150 | 2 5 | 10 | 360 | 5 6 | 200 | 360 | 1 7 | 200 | 420 | 2 8 | 200 | 420 | 2 9 | 200 | 500 | 4 10 | 200 | 500 | 4
    --
    -- Emulating RANK via a correlated sub-query
    --
    select *, 
    (select count(t2.value)+1 from yourtable t2 
     where t2.Group1 = t.Group1
       and t2.Value < t.Value) as Ranknum
    from yourtable t
    order by Group1, Ranknum
    
    身份证 |组1 |价值 |秩数 -: | -----: | ----: | ------: 1 | 10 | 100 | 1 2 | 10 | 150 | 2 3 | 10 | 150 | 2 4 | 10 | 150 | 2 5 | 10 | 360 | 5 6 | 200 | 360 | 1 7 | 200 | 420 | 2 8 | 200 | 420 | 2 9 | 200 | 500 | 4 10 | 200 | 500 | 4
    --
    -- DENSE_RANK (same values get same rank, without gaps)
    --
    select *
    , DENSE_RANK() over (partition by Group1 order by Value) as Ranknum
    from yourtable
    order by Group1, Ranknum
    
    身份证 |组1 |价值 |秩数 -: | -----: | ----: | ------: 1 | 10 | 100 | 1 2 | 10 | 150 | 2 3 | 10 | 150 | 2 4 | 10 | 150 | 2 5 | 10 | 360 | 3 6 | 200 | 360 | 1 7 | 200 | 420 | 2 8 | 200 | 420 | 2 9 | 200 | 500 | 3 10 | 200 | 500 | 3
    --
    -- Emulating DENSE_RANK via a correlated sub-query
    --
    select *, 
    (select count(distinct t2.Value) from yourtable t2 
     where t2.Group1 = t.Group1
       and t2.Value <= t.Value
    ) as Ranknum
    from yourtable t
    order by Group1, Ranknum
    
    身份证 |组1 |价值 |秩数 -: | -----: | ----: | ------: 1 | 10 | 100 | 1 2 | 10 | 150 | 2 3 | 10 | 150 | 2 4 | 10 | 150 | 2 5 | 10 | 360 | 3 6 | 200 | 360 | 1 7 | 200 | 420 | 2 8 | 200 | 420 | 2 9 | 200 | 500 | 3 10 | 200 | 500 | 3

    db小提琴here

    【讨论】:

    • 替代解决方案有效,但前提是值是唯一的。否则,重复值从上一组的下一个编号开始计数。
    • 现在应该修复了。必须用 () 包围 OR
    • 现在可以了,除了按Rownum排序,不能按它排序。
    • 谢谢。好吧,要对其进行排序,可以始终将其包装在子查询中,然后在子查询之外对其进行排序。
    【解决方案2】:

    考虑:

    SELECT Data.ID, Data.Group1, Data.Value, 
    DCount("*","Data","Group1='" & [Group1] & "' AND Value<" & [Value])+1 AS GrpSeq
    FROM Data
    ORDER BY Data.Value;
    

    或者

    SELECT Data.ID, Data.Group1, Data.Value, (
           SELECT Count(*) AS Cnt FROM Data AS Dupe 
           WHERE Dupe.Value<Data.Value AND Dupe.Group1=Data.Group1)+1 AS GrpSeq
    FROM Data
    ORDER BY Data.Value;
    

    【讨论】:

    • 第二种方法运行良好,但第一种方法在 Grpseq 上出错。
    • 为我工作。两者都有相同的输出。可能第二个在大型数据集上执行得更快。
    • 现在好了,两者都工作正常我找到了错误的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多