【问题标题】:How to find the max character using a substring如何使用子字符串查找最大字符
【发布时间】:2019-09-07 21:07:43
【问题描述】:

这应该相对容易。我以看索赔数据为生。我有以下假设的 ClaimID:17060C048388A3

关于这个,第14个字符空间中的A代表“调整”,下面的数字是调整的时间数。因此,例如,此特定声明已调整 3 次。 不幸的是 ClaimID 17060C048388A1、17060C048388A2 和 17060C048388A3(所有三个调整都显示)。在计算这些索赔时,我如何只选择最高调整以避免重复。并非所有声明都进行了调整,因此它们并非全都是 A,也不全是 15 个字符。

所以我想我需要如下开始一个case语句:

SELECT DISTINCT TOP 10000 *,
    CASE WHEN CLAIMID LIKE '%A%' THEN ??????

如果 ClaimID 中有“A”,则有关获取 ClaimID 中“A”之后的下一个最高数字的任何建议。因此,如果索赔有 8 次调整,我只想查看以 A8 结尾的那一项。

在此先感谢各位, 格雷格

【问题讨论】:

  • 您使用的是哪个 dbms(mysql、sql-server、oracle、postgres)?请标记您的问题。
  • Sql_Server 2016 管理工作室
  • 如果上面没有说清楚,表示调整的“A”并不总是在第 14 位。
  • 你们怎么看这个。查看数据,“A”可能位于第 13 位或第 14 位。这不应该解决问题吗?
    `SELECT DISTINCT claimid <br/> CASE WHEN SUBSTRING(CLAIMID, 14, 1) = 'A' Then Max(ClaimID) <br/> WHEN SUBSTRING(CLAIMID, 13, 1) = 'A' Then Max(ClaimID) End as MaxClaimID <br/> FROM PLANREPORT_QNXT_LA.DBO.CLAIM <br/> WHERE CLAIMID LIKE '%A%' <br/> group by claimid

标签: sql sql-server case sql-like sql-server-2016


【解决方案1】:

我再次查看了您的问题并创建了以下解决方案:

SELECT base, MAX(adjustment) AS max_adjustment, base + IIF(MAX(adjustment) > 0, 'A', '') + MAX(adjustment) max_adjusted_claim
FROM (
  SELECT 
    IIF(PATINDEX('%A%', ClaimID) = 0, ClaimID, LEFT(ClaimID, PATINDEX('%A%', ClaimID)-1)) AS base, 
    REPLACE(REVERSE(LEFT(REVERSE(ClaimID), PATINDEX('%A%', REVERSE(ClaimID)))), 'A', '') AS adjustment
  FROM table_name
)t GROUP BY base

demo on dbfiddle.uk

【讨论】:

  • 如果上面不明确,表示调整的“A”并不总是在第 14 位。
  • @GregoryBrauninger - 我更新了我的解决方案,现在应该适用于许多可能性(查看带有一些测试值的演示)。
【解决方案2】:

这样会更简单;

select * from Table1 where
regexp_like("column1",substr("column1",1,instr("column1",'A'))||
            (select max(substr("column1",-1)) from Table1) );`

检查这个:http://sqlfiddle.com/#!4/cb16f/7

【讨论】:

    【解决方案3】:

    使用 CTE:

    with cte as(
      select
        claimid,
        case 
          when claimid like '%A%' then left(claimid, charindex('A', claimid) - 1) 
          else claimid
        end claim,
        case 
          when claimid like '%A%' then cast(right(claimid, len(claimid) - charindex('A', claimid)) as int)
          else 0
        end adjustment
      from tablename
    )
    select distinct top 10000 t.* 
    from tablename t inner join (
      select 
        claim + 
        case max(adjustment) 
          when 0 then ''
          else 'A' + cast(max(adjustment) as varchar(10))
        end claimid 
      from cte
      group by claim
    ) g on g.claimid = t.claimid
    

    请参阅demo
    对于此示例数据:

    > claimid        | value
    > :------------- | :----
    > 17060C048388A1 | a    
    > 17060C048388A2 | b    
    > 17060C04838811 | c    
    > 17060C04838866 | d    
    > 17060C04838855 | e    
    > 17060C048388A3 | f    
    > 17060C04838899 | g 
    

    结果是:

    > claimid        | value
    > :------------- | :----
    > 17060C04838811 | c    
    > 17060C04838866 | d    
    > 17060C04838855 | e    
    > 17060C048388A3 | f    
    > 17060C04838899 | g 
    

    【讨论】:

      【解决方案4】:

      这对我有用(假设我没有注意到任何错误)。我从所有 cmets 中提取了示例并将其放在一起,谢谢大家的回答。

      SELECT DISTINCT SUBSTRING(CLAIMID, 1,13) + MAX(RIGHT(CLAIMID, 2)) AS 
      MAX_CLAIM_ADJUSTMENT
      FROM LA_TEMP.DBO.ITEM19
      WHERE (SUBSTRING(CLAIMID, 14, 1) = 'A'
      OR SUBSTRING(CLAIMID, 13, 1) = 'A')
      GROUP BY left(CLAIMID, 13)
      UNION
      SELECT DISTINCT SUBSTRING(CLAIMID, 1,14) + MAX(RIGHT(CLAIMID, 1)) AS 
      MAX_CLAIM_ADJUSTMENT
      FROM LA_TEMP.DBO.ITEM19
      WHERE (SUBSTRING(CLAIMID, 15, 1) = 'A'
      OR SUBSTRING(CLAIMID, 14, 1) = 'A')
      GROUP BY left(CLAIMID, 14)
      ORDER BY MAX_CLAIM_ADJUSTMENT
      

      我注意到 A 可以是第 13 个或第 14 个字符。

      【讨论】:

      • 当 A 后面的数字超过 1 位时,您的代码将失败,因为您将该数字作为字符串获取,因此如果存在 A10,您将获得 A9 作为最大值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多