преобразование столбцов базы данных в связанные данные строки - PullRequest
0 голосов
/ 03 января 2012

Я унаследовал старую базу данных доступа, которая включает таблицу с данными, организованными так:

+-------+--------+-------------+-------------+-------------+----------------+
| Code  |  Year  |  Category1  |  Category2  |  Category3  |  ... etc ...   |
+-------+--------+-------------+-------------+-------------+----------------+
| A     |  2011  |          1  |          4  |         12  |                |
| A     |  2012  |          5  |          33 |         24  |                |
| B     |  2012  |          4  |          11 |         76  |                |
+-------+--------+-------------+-------------+-------------+----------------+

Мне нужно изменить это (фактическая таблица имеет много столбцов) на следующую структуру:

+-------+--------+-------------+--------+
| Code  |  Year  |  Cat        |  Value |
+-------+--------+-------------+--------+
| A     |  2011  |  Category1  | 1      |
| A     |  2011  |  Category2  | 4      |
| A     |  2011  |  Category3  | 12     |
| A     |  2012  |  Category1  | 5      |
| A     |  2012  |  Category2  | 33     |
| A     |  2012  |  Category3  | 24     |
| B     |  2012  |  Category1  | 4      |
| B     |  2012  |  Category2  | 11     |
| B     |  2012  |  Category3  | 76     |
+-------+--------+-------------+--------+

Можно ли сделать это через автоматическое преобразование в MS Access (у меня версия 2010)?

1 Ответ

5 голосов
/ 03 января 2012

Вы можете использовать объединенный запрос:

SELECT a.* INTO NewTable FROM (
  SELECT [Code], [Year], "Category1" As Cat, Category1 As CatVal FROM MyTable
  UNION ALL
  SELECT [Code], [Year], "Category2" As Cat, Category2 As CatVal FROM MyTable
  UNION ALL
  <...> ) As a

Вы можете исключить зарезервированное слово "Год", пока оно у вас: http://support.microsoft.com/kb/321266

Если у вас много категорий, вы можете использовать VBA, чтобы облегчить жизнь, например:

Sub UnionSQL(ArrayColCommonWord As String, TableName As String)
Dim db As Database

Set db = CurrentDb

For Each fld In db.TableDefs(TableName).Fields
    If Left(fld.Name, Len(ArrayColCommonWord)) <> ArrayColCommonWord Then
        sSQL1 = sSQL1 & ",[" & fld.Name & "]"
    End If
Next

sSQL1 = "SELECT " & Mid(sSQL1, 2)

For Each fld In db.TableDefs(TableName).Fields
    If Left(fld.Name, Len(ArrayColCommonWord)) = ArrayColCommonWord Then
        sSQL = sSQL & vbCrLf & "UNION ALL" & vbCrLf
        sSQL = sSQL & sSQL1 & ",'" & fld.Name & "' As " & ArrayColCommonWord _
            & ",[" & fld.Name & "] As " & ArrayColCommonWord & "Val"
        sSQL = sSQL & vbCrLf & "FROM [" & TableName & "]"
    End If
Next

Debug.Print Mid(sSQL, 14)
''This will fail if there is an existing query
db.CreateQueryDef ArrayColCommonWord, Mid(sSQL, 14)

DoCmd.OpenQuery ArrayColCommonWord, acViewDesign

End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...