【问题标题】:In MS Access, How do I extract multiple values in a single column?在 MS Access 中,如何在单个列中提取多个值?
【发布时间】:2022-01-12 18:48:42
【问题描述】:

如何从单个列中解析多个值? 问题是多个值被无关的(出于我的目的)数据包围。 示例:

Select * from my_table:
Fname   Lname    Data
Fred    Smith    @3aXXXX;Name:AA;@43deXXXX;Name:BB;@5433ed9;NAME:ABC;*#!XXXXXXXX;NAME:MyPetDog;@#IDXXXX

对于数据列,我想从列中提取“名称:”字段后面的所有值。这将是 "Name:" 之后和 ";" 之前的文本。在上面的例子中:

Select Fname, Lname, [DATA] from my_table

Fname   Lname    [*Parsed* DATA]
Fred    Smith    AA,BB, ABC, MyPetDog

解决上述问题将是一个巨大的帮助。但是,我真正想做的是查找/替换(SWITCH 等)从字符串返回的每个值:

Fname   Lname    [Translated DATA]
Fred    Smith    Airport, Bus Station, Restaurant, FIDO

对于使用名义数据,我深表歉意。我的实际脚本(在另一个网络上)涉及几个表连接以获取列 DATA。我只是不知道如何从这个大字符串中提取特定值(除了提取完整数据集并在之后使用 AWk 或 MS Excel 清理数据)。

感谢有关解决此问题的任何帮助或提示。

凯文 L.

【问题讨论】:

    标签: sql ms-access


    【解决方案1】:

    按照@AppleCore 的建议,使用外部函数来避免混乱。

    SELECT 
        Fname, 
        Lname, 
        CleanField([Data]) AS TranslatedData
    FROM 
        my_table;
    

    将函数(使用Select Case .. 进行转换)复制粘贴到一个新模块中,进入菜单Debug, Compile,然后将该模块另存为Module1_:

    Public Function CleanField(ByVal Value As String) As String
    
        Dim Parts   As Variant
        Dim Index   As Integer
        Dim Part    As String
        Dim Text    As String
        
        Parts = Split(";" & Value, ":")
        For Index = LBound(Parts) To UBound(Parts)
            Part = Split(Parts(Index), ";")(0)
            
            Select Case Part
                Case Is = "AA"
                    Part = "Airport"
                Case Is = "BB"
                    Part = "Bus station"
                Case Is = "ABC"
                    Part = "Restaurant"
                Case Is = "MyPetDog"
                    Part = "FIDO"
            End Select
            
            If Part <> "" Then
                If Text <> "" Then
                    Text = Text & ", "
                End If
                Text = Text & Part
            End If
        Next
        
        CleanField = Text
    
    End Function
    

    例子:

    Fname   Lname   TranslatedData
    ------- ------- --------------------------------------
    Fred    Smith   Airport, Bus station, Restaurant, FIDO
    George  Olsen   Airport, Restaurant, Bus station, FIDO
    Tina    Doe     Restaurant, Bus station, FIDO
    

    【讨论】:

      【解决方案2】:

      我建议创建一个小的 VBA 函数,它获取“丑陋”数据并使用 Split 函数将其拆分出来。比如:

      Public Function fSplitData(strData As String) As String
          Dim aData() As String
          Dim lngLoop1 As Long
          aData = Split(strData, ";")
          For lngLoop1 = LBound(aData) To UBound(aData)
              If Left(aData(lngLoop1), 5) = "Name:" Then
                  fSplitData = fSplitData & Mid(aData(lngLoop1), 6) & ","
              End If
          Next lngLoop1
          If Right(fSplitData, 1) = "," Then fSplitData = Left(fSplitData, Len(fSplitData) - 1)
      End Function
      

      这给出了所需的输出:

      AA,BB,ABC,MyPetDog
      

      而且,您可以使用记录集从查找表中获取数据,而不仅仅是连接提取的值。在您的情况下,由于您只有 8 个值,您可以在代码中使用 If

      Public Function fSplitData(strData As String) As String
          Dim strLookup As String
          Dim aData() As String
          Dim lngLoop1 As Long
          aData = Split(strData, ";")
          For lngLoop1 = LBound(aData) To UBound(aData)
              If Left(aData(lngLoop1), 5) = "Name:" Then
                  strLookup = Mid(aData(lngLoop1), 6)
                  If strLookup = "AA" Then
                      fSplitData = fSplitData & "Airport,"
                  ElseIf strLookup = "BB" Then
                      fSplitData = fSplitData & "Bus Station,"
                  ElseIf strLookup = "ABC" Then
                      fSplitData = fSplitData & "Restaurant,"
                  ElseIf strLookup = "MyPetDog" Then
                      fSplitData = fSplitData & "FIDO,"
                  End If
              End If
          Next lngLoop1
          If Right(fSplitData, 1) = "," Then fSplitData = Left(fSplitData, Len(fSplitData) - 1)
      End Function
      

      然后您可以在查询中使用此函数,就像使用标准 Access 函数一样。所以你的 SQL 看起来像:

      SELECT 
      FName, 
      LName, 
      Data, 
      fSplitData([Data]) AS TranslatedData
      FROM Table1;
      

      问候,

      【讨论】:

      • 我非常感谢您的回复...但是,我不知道如何在我的 Access 数据库中进行测试?但是,我喜欢进行查找的想法,并且基于上面我确实尝试解码,但评估使用“SWITCH”。我的“NAME:”值限制为八个值,所以我添加了:
      • 我已将代码修改为仅使用一系列 If 语句来“翻译”数据,并展示了如何在查询中使用该函数。
      【解决方案3】:

      感谢@Applecore,我有一个几乎可以工作的解决方案(虽然可能不是最好的解决方案):

      SELECT Fname,
             Lname,
             SWITCH(data like "*AA*","Airport")&", "&
             SWITCH(data like "*BB*", "Bus Station")&", "&
             SWITCH(data like "*ABC*", "Restaurant")&", "&
             SWITCH(data like "*MyPetDog*","FIDO") as DATA
      
      Fname   Lname    [Translated DATA]
      Fred    Smith    Airport, Bus Station, Restaurant, FIDO
      

      唯一的问题是,如果值不存在,那么我会得到额外的逗号。例如,如果 BB 是唯一存在的值,那么我得到:

      Fname   Lname    [Translated DATA]
      Fred    Smith    , Bus Station, , 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-23
        • 2021-11-17
        • 2011-05-21
        • 1970-01-01
        • 1970-01-01
        • 2022-01-08
        • 1970-01-01
        相关资源
        最近更新 更多