【问题标题】:Sequence based on the condition using SQL使用 SQL 根据条件排序
【发布时间】:2021-09-24 02:03:57
【问题描述】:

我需要根据一列中的数据创建一个序列,示例表如下:

id | group 
101| bfd   
102| bfd
123| klm
563| kln
693| klm

要提供的序列是这样的,如果 group = bfd 那么 new_id = id + 中的序列 如果 group = klm 或 kln 则 new_id = id +

中的序列

输出应该是这样的:

id | group | new_id
101| bfd   | 1010 
102| bfd   | 1021
123| klm   | 123201
563| kln   |563202
693| klm   | 693203

我尝试了以下代码

select * from(
SELECT id, group,
CASE
    WHEN group in 'bfd' THEN concat(ID, -1 +ROW_NUMBER() OVER(PARTITION BY group order by ID))  
    WHEN group='klm' or group="kln" THEN concat(ID, 200 + ROW_NUMBER() OVER(PARTITION BY group order by id))
    END  as new_id
FROM table2)
order by id;

如何为特定组提供行号停止在 200 处的限制条件?

【问题讨论】:

  • 如果有201个bfd你会怎么做?反复使用200?不为所有后续的内容添加任何内容?
  • 为什么你认为你甚至需要这个新的 ID 列?请注意,即使您在这里得到了答案,如果您的表数据发生变化,或者应该添加新数据,您也可能需要重新计算新的 ID 列。
  • 顺便说一句,在您的预期输出中,您将klmkln 视为具有相同运行顺序的同一组。但是您的查询无法处理 OVER(PARTITION BY group order by id)
  • 同意松鼠,也许你应该有一个LEFT(group,1)作为你的分区
  • 你需要解释如果除了上面提到的组之外还有其他组并且当组中的行数超过200时会发生什么。

标签: sql sql-server database tsql


【解决方案1】:

将连接移至外部查询:

select *, CASE WHEN new_id_bit > 200 THEN ... ELSE concat(ID, CASE WHEN group = 'bfd' THEN -1 ELSE 200 END + NEW_id_bit) end

FROM(
SELECT id, group,ROW_NUMBER() OVER(PARTITION BY group order by ID)  as new_id_bit
FROM table2)x
order by id;

如果超过200我不知道你想做什么;用你自己的逻辑代替 ... ,例如CASE WHEN new_id_bit > 200 THEN 200 ELSE new_id_bit END

您也可以/改为使用 where 子句来限制只有那些新 ID 位小于 200 的人

【讨论】:

  • 我是 IT 领域的新手,尝试使用 SQL,这帮助我了解了很多功能谢谢!
  • 没问题!顺便说一句,您本可以按照您的方式保留它,但这意味着在您需要的任何地方重复冗长的ROW_NUMBER() OVER(PARTITION BY group order by ID)。通过在内部查询中执行此操作,您可以为其创建别名,然后在CASE WHEN x = blah THEN x ELSE x + 1 END 等许多地方更容易重用 - 它比CASE WHEN ROW_NUMBER() OVER(PARTITION BY x ORDER BY y) = blah THEN ROW_NUMBER() OVER(PARTITION BY x ORDER BY y) ELSE ROW_NUMBER() OVER(PARTITION BY x ORDER BY y) + 1 END 更具可读性:D
【解决方案2】:
select t1.id,
 t1.g,
 convert(varchar(3), t1.id)
    + convert ( varchar(3),
   case when g = 'bfd' then ROW_NUMBER() over ( partition by case when g = 'bfd' then 1 else 2 end order by id) - 1
   else (ROW_NUMBER() over ( partition by case when g = 'bfd' then 1 else 2 end order by id)) + 200 end)
from T t1 

输出

101 bfd 1010
102 bfd 1021
123 klm 123201
563 kln 563202
693 klm 693203

【讨论】:

  • 这似乎没有解决 OP 对stop at 200 for particular group的要求
  • 我也很难得到这个订单!谢谢你的协助!这有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-09
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多