在CASE语句中,使用带有生成序列ID的子查询

问题描述 投票:0回答:2

CASE语句中我使用了子查询,在子查询中我们想要一个列以及自动序列值或计数器值。例如 - 在CASE语句中查询是这样的,我们在col1条件中将一列作为WHERE传递并获得col2CNT的输出。

(CASE WHEN (SELECT COL2, ROWNUM AS CNT FROM TAB1 WHERE COL1 = COL1) THEN ....)

只要任何值col1匹配,那么col2的输出将与CNT的增量值一起生成。

CNT在这里是计数器值,如1,2,3,4,.....哪一个是更好的选择使用计数器或序列。

sql oracle case
2个回答
1
投票

“哪一个更好的选择是使用计数器还是序列。”

你是否一直希望CNT从1开始?如果是这样,您不需要序列。

为CNT生成值有多种不同的方法。最简单的是使用rownum伪列:

 SELECT COL1, rownum as CNT FROM TAB1 WHERE  

当你不关心给定的行是12还是99999时,这是一个很好的解决方案。如果您有一些特殊要求,您可能需要使用像row_number()这样的分析函数:

 SELECT COL1, row_number() over (order by COL2) as CNT FROM TAB1 WHERE  

1
投票

通常,“更好”取决于您尝试做什么。

有几种可能的情况:

  1. 您将结果集返回给某些调用代码/用户。调用序列可能是不必要的开销,并且不允许更复杂的行编号表达式。 在这种情况下,我会使用最合适的rownum和各种分析行编号函数,row_number()rank()dense_rank() 由于您的查询是如何构造的,因此您可能应该使用此方法。
  2. 您将此数据插入表中。我更喜欢序列是标识列,或者在12c之前,是在触发器中。这是因为除了单个语句之外的代码可能会执行插入操作,并且您希望确保更改表中数据的所有传入数据都以相同的方式处理。 换句话说,不要在代码中使用序列来执行此操作。
  3. 您将生成一个唯一的标识,您将向用户显示该标识然后插入到表中。如果您有手动批准步骤,这种结构最有用。由于(2)中详述的原因,您希望使用序列来确保数据处理相同。 另一种可能导致锁定的方法是进行插入,然后将未提交的数据显示给用户。然后,用户必须适当地提交或回滚。 如果您正在执行其中任何一项,您将丢失未提交的序列值。这根本不重要,但由于某些原因它会困扰一些人。
© www.soinside.com 2019 - 2024. All rights reserved.