有没有一种简单的方法来取消交叉表查询 table? (归一化)
Is there an easy way to un-crosstab query a table? (normalize)
我刚刚继承了一个新的数据库来维护。但是 table 中的一个并不好。我可以编写一个复杂的查询来解决这个问题,但这将是冗长乏味的。我想知道是否有更简单的方法?
table 看起来像这样:
Name
Data point
Date1
date 2
date 3
date 4
...
dateN
alpha
yes
date
date
date
date
...
date
beta
no
date
date
date
date
...
date
事实是,我需要它看起来像这样:
Name
Data point
DateCat
Date
alpha
yes
date1
date
beta
no
date2
date
alpha
yes
date3
date
beta
no
date4
date
alpha
yes
date2
date
beta
no
date1
date
现在交叉表可以让我从我想要的变成我拥有的,有没有一种简单的方法可以反过来,或者这是一种“亲自动手并手动完成”的情况?我正在考虑导出 table,将其放入 pandas 并以这种方式进行操作,因为我知道我可以在那里进行操作。希望 Access 有内置的东西吗?
虽然 Access 没有一个内置函数来做你想做的事,但使用 VBA 创建一些东西相对容易,它循环第一个 table 中的字段以输出根据需要的数据。类似于:
Sub sUnXTabData()
On Error GoTo E_Handle
Dim db As DAO.Database
Dim rsSteer As DAO.Recordset
Dim rsData As DAO.Recordset
Dim intCount As Integer
Dim intLoop1 As Integer
Set db = CurrentDb
Set rsSteer = db.OpenRecordset("SELECT * FROM tblXTab;")
If Not (rsSteer.BOF And rsSteer.EOF) Then
db.Execute "DELETE * FROM tblNotXTab;"
Set rsData = db.OpenRecordset("SELECT * FROM tblNotXTab WHERE 1=2;")
intCount = rsSteer.Fields.Count - 1
Do
For intLoop1 = 2 To intCount
rsData.AddNew
rsData("Name") = rsSteer("Name")
rsData("Datapoint") = rsSteer("Datapoint")
rsData("DateCat") = rsSteer.Fields(intLoop1).name
rsData("Date") = rsSteer.Fields(intLoop1)
rsData.Update
Next intLoop1
rsSteer.MoveNext
Loop Until rsSteer.EOF
End If
sExit:
On Error Resume Next
rsSteer.Close
rsData.Close
Set rsSteer = Nothing
Set rsData = Nothing
Set db = Nothing
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sUnXTabData", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
请注意 Name
和 Date
是 Access 中的保留字,因此您应该更改它们。
此致,
我刚刚继承了一个新的数据库来维护。但是 table 中的一个并不好。我可以编写一个复杂的查询来解决这个问题,但这将是冗长乏味的。我想知道是否有更简单的方法?
table 看起来像这样:
Name | Data point | Date1 | date 2 | date 3 | date 4 | ... | dateN |
---|---|---|---|---|---|---|---|
alpha | yes | date | date | date | date | ... | date |
beta | no | date | date | date | date | ... | date |
事实是,我需要它看起来像这样:
Name | Data point | DateCat | Date |
---|---|---|---|
alpha | yes | date1 | date |
beta | no | date2 | date |
alpha | yes | date3 | date |
beta | no | date4 | date |
alpha | yes | date2 | date |
beta | no | date1 | date |
现在交叉表可以让我从我想要的变成我拥有的,有没有一种简单的方法可以反过来,或者这是一种“亲自动手并手动完成”的情况?我正在考虑导出 table,将其放入 pandas 并以这种方式进行操作,因为我知道我可以在那里进行操作。希望 Access 有内置的东西吗?
虽然 Access 没有一个内置函数来做你想做的事,但使用 VBA 创建一些东西相对容易,它循环第一个 table 中的字段以输出根据需要的数据。类似于:
Sub sUnXTabData()
On Error GoTo E_Handle
Dim db As DAO.Database
Dim rsSteer As DAO.Recordset
Dim rsData As DAO.Recordset
Dim intCount As Integer
Dim intLoop1 As Integer
Set db = CurrentDb
Set rsSteer = db.OpenRecordset("SELECT * FROM tblXTab;")
If Not (rsSteer.BOF And rsSteer.EOF) Then
db.Execute "DELETE * FROM tblNotXTab;"
Set rsData = db.OpenRecordset("SELECT * FROM tblNotXTab WHERE 1=2;")
intCount = rsSteer.Fields.Count - 1
Do
For intLoop1 = 2 To intCount
rsData.AddNew
rsData("Name") = rsSteer("Name")
rsData("Datapoint") = rsSteer("Datapoint")
rsData("DateCat") = rsSteer.Fields(intLoop1).name
rsData("Date") = rsSteer.Fields(intLoop1)
rsData.Update
Next intLoop1
rsSteer.MoveNext
Loop Until rsSteer.EOF
End If
sExit:
On Error Resume Next
rsSteer.Close
rsData.Close
Set rsSteer = Nothing
Set rsData = Nothing
Set db = Nothing
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sUnXTabData", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
请注意 Name
和 Date
是 Access 中的保留字,因此您应该更改它们。
此致,