我希望生成一个基于条件的列 第3列应该生成一个运行编号,并且应该在第2列的值> 1时开始。 0
Col1 ColM Col2 Col 3
AA 1 0 0
AA 2 0 0
AA 3 223 1
AA 4 44 2
AA 5 5 3
AA 6 55 4
BB 1 0 0
BB 2 0 0
BB 3 0 0
BB 4 0 0
BB 5 11 1
BB 6 22 2
请帮助我,并提前感谢您查看此内容
答案 0 :(得分:2)
您可以通过计算在值之前出现的零的数量来识别非零的第2列值组:
select t.*,
(select count(*)
from table as t2
where t2.col2 = 0 and
t2.col1 < t.col1 or t2.col1 = t.col1 and t2.colM <= t.colM
) as grp
from table as t;
接下来,您可以将其用作子查询来枚举每个组内的行。这有点讨厌:
select t.col1, t.colM, t.col2,
iif(t.col2 = 0, 0, count(*) - 1) as col3
from (select t.*,
(select count(*)
from table as t2
where t2.col2 = 0 and
t2.col1 < t.col1 or t2.col1 = t.col1 and t2.colM <= t.colM
) as grp
from table as t
) as t join
(select t.*,
(select count(*)
from table as t2
where t2.col2 = 0 and
(t2.col1 < t.col1 or t2.col1 = t.col1 and t2.colM <= t.colM)
) as grp
from table as t
) as tgrp
on tgrp.grp = t.grp and
(tgrp.col1 < t.col1 or tgrp.col1 = t.col1 and t2.colM <= t.colM)
group by t.col1, t.colM, t.col2;
逻辑将前面的0指定给同一个组,大于0的值。这就是-1
中需要select
的原因。
这在大多数其他数据库中会容易得多,因为它们支持窗口函数。
答案 1 :(得分:1)
如果您可以使用VBA,请将以下代码添加到模块中:
Dim lastCol1 As String, lastCount As Integer
Function RunningConditionalCount(col1 As String, col2 As Integer) As Integer
If lastCol1 <> col1 Then
lastCount = 0
lastCol1 = col1
End If
If col2 > 0 Then lastCount = lastCount + 1
RunningConditionalCount = lastCount
End Function
并称之为:
SELECT [table].*, RunningConditionalCount(col1,col2) AS Expr1
FROM [table]
ORDER BY table.col1, table.colM;
这是有效的,因为模块级变量(lastCol1
和lastCount
)在调用之间保留它们的值。
一个问题 - 在您的数据中,Col1
有多个唯一值。如果某个数据集只包含Col1
的唯一值,则lastCol1
将永远不会重置。如果有可能,那么您必须通过创建Sub
来明确重置它:
Sub Reset()
lastCol1 = ""
End Sub
并在运行查询之前在代码中调用它。
或者,您可以使用硬编码值将函数调用一次作为UNION
查询的一部分,然后排除生成的记录:
SELECT col1, col2, colM, Expr1
FROM (
SELECT TOP 1 "" AS Col1, 0 AS ColM, 0 AS Col2, RunningConditionalCount("",0) AS Expr1, 0 AS RowType
FROM [table]
UNION ALL SELECT [table].*, RunningConditionalCount(col1,col2) AS Expr1, 1
FROM [table]
) AS t1
WHERE RowType=1
ORDER BY col1, colM