Access中的IIF语句会破坏层次结构中稍后重叠的值

我部分地提炼了一个早先的问题,试图在这里提出一些具体的问题。 为了解决这个问题,我有一个有点大的数据集(大约250k行),我需要根据是否在字段中find某个文本string,将给定的连接字段转换为每个行项目的输出。 这已经在Excel中pipe理(使用IF(IFERROR(FIND())),但是公式对Excel太重要了,我需要将整个过程移到Access以更好地自动化。最终目标是生成一个表格可以粘贴到一个Excel模型,然后刷新修改date。

现有的SQL:

SELECT my_field_1 , my_field_2, my_field_3, IIF(Active = 'Yes' AND Issue IS NULL,'OK', IIF(Issue LIKE '123','123', IIF(Issue LIKE'234','234', IIF(Issue LIKE '345','345', //* Etc going down to 14 nested IIF statements in the above format and //* returning NULL where conditions are not met. I then roll up the 3 issue //* sets as follows IIF(IssueSet1 IS NOT NULL, IssueSet1, IIF(IssueSet2 IS NOT NULL, IssueSet2, IIF(IssueSet3 IS NOT NULL, IssueSet3, 'Check for errors'))) 

期望的输出

',123,234'应该将成功的查询输出中的'123'返回到RollUp列。

按照上述格式,层次结构被拆分为2组14个嵌套IIF语句,第3个嵌套IIF语句为3个。 然后我把上面所有的IIF声明汇总起来。 不幸的是,Access正在返回CA. 在同一行之后的IIF之前触发较早的IIF,例如1行满足IIF的条件,这是不可避免的,因为我需要使用这个层次来“排列”更紧迫的问题在层次结构中。

问题:

  • 如果层次结构首先触发“123”,但是在同一个行项目中出现“234”,则返回NULL,而不是返回123.有没有什么办法可以让这个停止发生,所以层次结构中的任何东西都会胜过它? 如果我可以在Access以外的平台上这样做的话,这在CASE声明中可以正常工作,这非常令人沮丧。

  • 现有的格式是笨重的,我宁愿使用查阅列和永久表,但我不知道如何只返回我需要的值(例如'123'),而不是整个字段(例如',123,234,345,456')

  • 我需要最终生成一个汇总输出,可以很容易地复制和粘贴到相当一个Excel模型(或通过VBA自动input),它提供了问题ID(IIF生成),类别(已经存在),子类别(已经存在),伯爵(总和问题ID,类别和子类别,如果我sorting这个IIF问题,我可以自己做)。

非常感谢,我希望这澄清了我正在尝试做什么。

Ĵ

Issue LIKE '123'相当于Issue = '123'因为该模式不包含任何通配符 。

如果你打算说“ Issue包含'123' ,那将是Issue LIKE '*123*'
但是,您必须确保您不会意外指定一个更长可能值的子string。 例如,如果Issue中的值列表包含'...,987123,...' ,那么您可能不想匹配123 ,但匹配。

最好的办法是将问题parsing为某种数组,并查看它是否包含值。 例如,通过编写一个VBA函数并在查询中使用它:

 Option Compare Database Public Function ContainsInList(ByVal CommaSeparatedList As Variant, ByVal Value As Variant) As Boolean If IsNull(CommaSeparatedList) Then Exit Function If IsEmpty(CommaSeparatedList) Then Exit Function If IsNull(Value) Then Exit Function If IsEmpty(Value) Then Exit Function If Len(CommaSeparatedList) = 0 Then Exit Function If Len(Value) = 0 Then Exit Function ContainsInList = InArray(Split(CommaSeparatedList, ","), Value) End Function Public Function InArray(ByRef Arr As Variant, ByVal Value As Variant) As Boolean Dim i As Long For i = LBound(Arr) To UBound(Arr) If Arr(i) = Value Then InArray = True Exit Function End If Next End Function 
 SELECT IIF(Active = 'Yes' AND Issue IS NULL,'OK', IIF(ContainsInList(Issue, '123'), '123', IIF(ContainsInList(Issue, '234'), '234', ... 

在这一点上,为您的123 s创build查找表并不难,例如:

 priority int not null, value varchar(50) not null 

并用它来代替嵌套的IF:

 SELECT IIF(Active = 'Yes' AND Issue IS NULL, 'OK', NZ((select top 1 [123s].value from [123s] where ContainsInList(Issue, [123s].value) order by [123s].priority), Issue))