【问题标题】:Find Max value and assign the value by group by id for non numeric field查找最大值并按 id 为非数字字段按组分配值
【发布时间】:2021-02-03 18:37:47
【问题描述】:

我正在尝试通过分组 id 字段来分配最大值。如果 id 有 L 和 M,结果应该是 M,如果 id 字段有 L、M 和 H,结果应该是 H。如果它只有一个值,则返回相同的值(L 代表 L,M 代表 M 和H 代表 H)。

这是我试过的代码:

select x2.id, x2.code, x1.output
from
(
select id, max(code) as output
from
table
group by id
)x1,
select id,code
from
table
)x2
where x1.id = x2.id
order by id

结果集与预期不符。我哪里错了?

【问题讨论】:

  • 根据所提供的信息,您认为人们可以如何帮助您?请阅读这个。 stackoverflow.com/help/how-to-ask
  • 数据请使用格式化文本,而不是图像。

标签: sql sql-server subquery case min


【解决方案1】:

这是一个使用窗口min()的选项:

select t.*,
    case min(case code 
        when 'H' then 1 
        when 'M' then 2 
        when 'L' then 3 
    end) over(partition by id)
        when 1 then 'H' 
        when 2 then 'M' 
        when 3 then 'L'
    end res
from mytable t

【讨论】:

    【解决方案2】:

    类似的东西。第一个 CTE 定义了一个层次结构表。

    数据

    drop table if exists #tTable;
    go
    create table #tTable(
      id            int not null,
      code          varchar(10) not null);
     
     Insert into #tTable values
    (1, 'h'),
    (2, 'l'),
    (3, 'm'),
    (10001, 'l'),
    (10001, 'l'),
    (10001, 'm'),
    (10001, 'l'),
    (10002, 'l'),
    (10002, 'l'),
    (10002, 'h'),
    (10002, 'l'),
    (10002, 'h'),
    (10002, 'm'),
    (10002, 'm');
    

    查询

    with
    v_cte(h, code) as (
        select *
        from (values (1, 'H'), 
                     (2, 'M'),
                     (3, 'L')) v(h, code)),
    max_cte as (
        select t.id, t.code, v.h, min(v.h) over (partition by t.id order by (select null)) min_h
        from #tTable t
             join v_cte v on t.code=v.code)
    select mc.id, mc.code, v.code [output]
    from max_cte mc
         join v_cte v on mc.min_h=v.h;
    

    输出

    id      code    output
    1       h       H
    2       l       L
    3       m       M
    10001   l       M
    10001   l       M
    10001   m       M
    10001   l       M
    10002   l       H
    10002   l       H
    10002   h       H
    10002   l       H
    10002   h       H
    10002   m       H
    10002   m       H
    

    【讨论】:

      【解决方案3】:

      看来code 代表高、中、低?

      要直接回答您的问题,我相信您的错误之处在于您期望MAX(code) 返回H。但是 SQL 对这些代码的含义一无所知。它返回具有最高字符/字典值的代码,在 ASCII/Unicode 中为“M”。

      因此,您需要一个查找表(@SteveC 建议)或查找表达式(@GMB 建议)将代码映射到数值(按正确顺序),并在调用 MAX 时使用该数值.我个人会选择这张桌子,因为(根据我的经验)你最终可能会遇到多个依赖于这种排序的查询。查找表是一种非常常见的机制,用于对优先级、状态等进行编码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-20
        • 1970-01-01
        • 1970-01-01
        • 2021-01-15
        • 1970-01-01
        • 2016-03-08
        相关资源
        最近更新 更多