在CASE语句中使用子查询生成序列ID

时间:2017-12-27 15:30:03

标签: sql oracle case

在我使用子查询CASE语句中,在子查询中,我们需要一列以及自动序列值或< strong> counter 值。例如- 在CASE语句中,查询就是这样,我们在col1条件&amp;中传递一列WHERE。获得col2输出以及CNT

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

只要任何值col1匹配,就会生成col2的输出以及CNT的增量值。

CNT此处的计数器值为1,2,3,4 ...... .....更好的选择是使用计数器还是序列

2 个答案:

答案 0 :(得分:1)

通常,“更好”取决于您尝试做的事情。

有几种可能的情况:

  1. 您将结果集返回给某些调用代码/用户。调用序列可能是不必要的开销,并且不允许使用更复杂的行编号表达式。

    在这种情况下,我会使用最合适的rownum和各种分析行编号函数,row_number()rank()dense_rank()

    由于您的查询是如何构建的,因此您可能应该使用此方法。

  2. 您正在将此数据插入表中。我更喜欢序列是标识列,或者在12c之前,是在触发器中。这是因为除了单个语句之外的代码可能会执行插入操作,并且您希望确保更改表中数据的所有传入数据都以相同的方式处理。

    换句话说,不要在代码中使用序列来执行此操作。

  3. 您正在生成一个唯一的标识,您将向用户显示该标识然后插入表格。如果您有手动批准,这种结构最有用步。由于(2)中详述的原因,您希望使用序列来确保数据处理相同。

    另一种可能导致锁定的方法是执行插入操作,然后将未提交的数据显示给用户。然后,用户必须适当地提交或回滚。

    如果您正在执行其中任何一项操作,您将丢失未提交的序列值。这根本不重要,但由于某些原因它会困扰一些人。

答案 1 :(得分: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