使用分隔符将SQL数据分成3列

我正在使用Excel VBA并使用OleDB连接到PGSQL。 不幸的是,oledb不允许引用聚合函数之外的列,因为group by已经被应用到表中,所以我必须连接数据,但是我无法将数据(latestBMI)分割回3个单独的列事件date|重量| bmi),因为重量和bmi值的长度不同,但是被pipe道分隔。

以下是通过提取的表格:

master_id : latestBMI 251 : 2008-05-08|84|26.8 2848 : 1992-11-23|86.71|27.3 2026 : 2002-04-16|105|31.6 22316 : 2014-02-28|107.955|35.1 16633 : 2005-07-04|70|25 9545 : 1997-04-08|82.73|24.9 

我一直在玩各种各样的方法尝试SUBSTRING,CHARINDEX,LEN,LEFT,RIGHT,但是失败。 这是我目前的代码,但重量和BMI的SUBSTRING元素是我的问题:

 Const sqlconnection = "Provider=oledb;" Dim conn As New Connection conn.ConnectionString = sqlconnection conn.Open Dim rs As Recordset Sheets("Sheet1").Select Range("A1").Select Dim DATA As String DATA = "SELECT latest.master_id, " _ & "SUBSTRING(latestBMI,1,10) eventdate, " _ & "SUBSTRING(latestBMI,12,CHARINDEX('|',latestBMI,RIGHT(latestBMI,7)) weight, " _ & "SUBSTRING(latestBMI,20,4) BMI " _ & "FROM ( " _ & "SELECT master_id, " _ & "MAX(CAST(eventdate AS VARCHAR(10)) + '|' + RIGHT(weightkg,7)+ '|' + RIGHT(bmi,4)) AS latestBMI " _ & "FROM weight " _ & "GROUP BY master_id) as latest " _ & "LEFT JOIN person p on latest.master_id = p.entity_id " Set rs = conn.Execute(DATA) With ActiveSheet.QueryTables.Add(Connection:=rs, Destination:=Range("A1")) .Refresh End With 

如何使用pipe道分隔符将它们分成3个独立的列?

如果您可以先取得数据,然后在表格中分割数据,那么试试(如果您知道最新的BMI数据将在B2:B7范围内)

Selection.TextToColumns目标:=范围(“B2:B7”),_
DataType:= xlDelimited,_
TextQualifier:= xlDoubleQuote,_
ConsecutiveDelimiter:= False,_
Tab:= False,_
分号:= False,逗号:= False,空格:= False,其他:= True,_
OtherChar:=“|”,_
FieldInfo:= Array(Array(1,1),Array(2,1),Array(3,1)),_
TrailingMinusNumbers:=真

我假设你的表有4列

master_id,BMI1,BMI2,BMI3和BMI4

您可以使用下面的查询生成INSERT语句,然后在数据库上运行它们

 select 'insert into newTable (master_id, BMI1, BMI2, BMI3) values( ' + cast(master_id as varchar) + ',''' + replace(latestBMI, '|', ''',''') + ''')' from #t 

它会生成以下语句(使用您的示例数据)

 insert into newTable (master_id, BMI1, BMI2, BMI3) values( 251,'2008-05-08','84','26.8') insert into newTable (master_id, BMI1, BMI2, BMI3) values( 2848,'1992-11-23','86.71','27.3') insert into newTable (master_id, BMI1, BMI2, BMI3) values( 2026,'2002-04-16','105','31.6') insert into newTable (master_id, BMI1, BMI2, BMI3) values( 22316,'2014-02-28','107.955','35.1') insert into newTable (master_id, BMI1, BMI2, BMI3) values( 16633,'2005-07-04','70','25') insert into newTable (master_id, BMI1, BMI2, BMI3) values( 9545,'1997-04-08','82.73','24.9') 

如果列不是整数,则可以修改SELECT语句以获得所需内容。 但是即使你的列是数字的,所生成的INSERT仍然可以工作。

有许多复杂的基于SQL /数据库的解决scheme(请参阅正确分割string ),在SQL语句完成后处理VBA中的数据将变得容易得多。

你的代码看起来像会产生一个如下所示的结果:

在这里输入图像描述

所以你应该循环遍历B列中的结果并将其分开。

 Option Explicit Sub test() SeparateFields ActiveSheet End Sub Sub SeparateFields(ws As Worksheet) '--- assumes your concatenated field (after your SQL ' statement) ends up in column B. The separated ' fields go in columns B, C, D. Dim concatFields As String Dim fields() As String Dim numRows As Long Dim i As Long numRows = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row For i = 2 To numRows concatFields = ws.Cells(i, 2).value fields = Split(concatFields, "|", , vbTextCompare) ws.Cells(i, 2).value = fields(0) ws.Cells(i, 3).value = fields(1) ws.Cells(i, 4).value = fields(2) Next i End Sub 

在您的代码导入您的数据后,只需使用文本到列来分离它。

  Sub SepDelCol() Columns("B:B").Select Selection.TextToColumns _ Destination:=Range("B:B"), _ DataType:=xlDelimited, _ TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, _ Tab:=False, Semicolon:=False, Comma:=False, Space:=False, _ Other:=True, OtherChar:="|" End Sub