MS Access - 将行值转换为列值
Posted
技术标签:
【中文标题】MS Access - 将行值转换为列值【英文标题】:MS Access - Convert rows values into columns values 【发布时间】:2020-03-11 14:40:39 【问题描述】:我需要使用 MS Access 转换下表:
进入 我该如何转换它?我是 ms access 2016 的新手。
我研究了ACCESS/SQL Combining multiple rows with one column into one row and creating multiple columns 中提供的解决方案。但无法获得我想要的结果。
【问题讨论】:
如果您为每个组合 ob 项目和资产添加一个唯一计数器作为单独的字段,那么您可以使用交叉表查询。 您可以在 MS SQL 服务器https://social.msdn.microsoft.com/Forums/sqlserver/en-US/e1e3af11-b740-4778-bfd6-7377c69ee0b5/i-need-to-combine-multiple-rows-into-a-single-row?forum=transactsql
上使用光标来完成此操作,但 Access 无法做到这一点。
【参考方案1】:
这是适用于 MS SQL 服务器的 sql 脚本:
create table #T (Project varchar(50),Asset varchar(50), OrderNo int)
insert into #T (Project, Asset, OrderNo) values ('ABC','K11',3245)
insert into #T (Project, Asset, OrderNo) values ('ABC','K11',4564)
insert into #T (Project, Asset, OrderNo) values ('ABC','K11',5234)
insert into #T (Project, Asset, OrderNo) values ('XYZ','M33',5346)
insert into #T (Project, Asset, OrderNo) values ('XYZ','M33',8745)
declare @Count int,@Cur int
declare @Qry nvarchar(4000)
set @Cur=1
select @Count=max(t.count) from (
select count(OrderNo) count from #T group by Asset)t
set @Qry=''
while @Cur<@Count+1
begin
set @Qry= @Qry + ',(select t.OrderNo from (select ROW_NUMBER() over(order by OrderNo) ROW_NUMBER, OrderNo from #T where Asset= t1.Asset) t where ROW_NUMBER='+ cast(@Cur as varchar(10)) + ') as OrderNo' + cast(@Cur as varchar(10))
set @Cur=@Cur+1
end
set @Qry='select distinct t1.Project, t1.Asset ' + @Qry + ' from #T t1 ORDER BY t1.Project'
print @Qry
exec sp_executesql @Qry
drop table #T
结果如下:
我认为你不能在 MS Access 中做到这一点。
【讨论】:
他要求 Microsoft Access 中的解决方案,而不是 Microsoft SQL Server。 ;-) @Unhandled Exception:你是对的,我完全意识到这一点。我也在编写 MS Access 并在 SQL 服务器上使用类似的脚本并从 Access 调用它。你不认为这将是一个解决方案吗?这可以帮助他。 当然,这可能是一个解决方案。使用 SQL Server 还应该有更多的方法来达到这个结果。只要他可以/可能使用 SQL Server。 我会对使用 SQL 的更多解决方案感兴趣。你有吗? 谢谢。我想看看我可以在 MS Access 中使用的解决方案。【参考方案2】:这是使用代码的纯 Access 解决方案。它可能会更有效,但你现在就会明白了。它会创建一个临时表Transposed
,您可以在其中找到结果。这是带有数据的 MyTable
这是给你的代码:
Option Compare Database
Option Explicit
Public Function Transpose() As String
Dim ordersCnt As Integer, sql As String, i As Integer, tempTable As String, f As Variant, myTable As String
Dim insSql As String, fieldsSql As String, updateSql As String, updateSql2 As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim grp As DAO.Recordset
tempTable = "Transposed"
myTable = "MyTable"
ordersCnt = GetMaxOrders
Set db = CurrentDb()
If Not IsNull(DLookup("Name", "MSysObjects", "Name='" & tempTable & "'")) Then
DoCmd.DeleteObject acTable, tempTable
End If
fieldsSql = ""
sql = "CREATE TABLE " & tempTable & " (Project CHAR, Asset CHAR "
For i = 1 To ordersCnt
fieldsSql = fieldsSql & ", Order" & i & " INTEGER"
Next i
sql = sql & fieldsSql & ")"
db.Execute (sql)
insSql = "INSERT INTO " & tempTable & " (Project, Asset) VALUES ("
Set grp = db.OpenRecordset("SELECT DISTINCT Project, Asset FROM " & myTable & " GROUP BY Project, Asset")
grp.MoveFirst
Do While Not grp.EOF
sql = "'" & grp(0) & "','" & grp(1) & "')"
db.Execute insSql & sql
Set rs = db.OpenRecordset("SELECT * FROM " & myTable & " WHERE Project = '" & grp(0) & "' AND Asset = '" & grp(1) & "'")
updateSql = "UPDATE " & tempTable & " SET "
updateSql2 = ""
i = 0
rs.MoveFirst
Do While Not rs.EOF
i = i + 1
updateSql2 = updateSql2 & "Order" & i & "= " & rs(3) & ","
rs.MoveNext
Loop
updateSql = updateSql & Left(updateSql2, Len(updateSql2) - 1) & " WHERE Project = '" & grp(0) & "' AND Asset = '" & grp(1) & "'"
db.Execute updateSql
grp.MoveNext
Loop
End Function
Public Function GetMaxOrders()
Dim rst As DAO.Recordset
Dim strSQL As String
strSQL = "SELECT MAX(CountOfOrderNo) FROM (SELECT Count(OrderNo) AS CountOfOrderNo FROM MyTable GROUP BY Project, Asset) "
Set rst = CurrentDb.OpenRecordset(strSQL)
GetMaxOrders = rst(0)
rst.Close
Set rst = Nothing
End Function
结果:
享受吧。
【讨论】:
感谢 Vlado 的解决方案。以上是关于MS Access - 将行值转换为列值的主要内容,如果未能解决你的问题,请参考以下文章