我需要根据条件在MS Access Query中运行一个数字

时间:2014-07-14 17:10:30

标签: sql ms-access

我希望生成一个基于条件的列 第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

请帮助我,并提前感谢您查看此内容

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;

这是有效的,因为模块级变量(lastCol1lastCount)在调用之间保留它们的值。

一个问题 - 在您的数据中,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