是否可以使用查询转置数据?

时间:2015-01-08 15:18:03

标签: sql ms-access

编辑: 标题可能会产生误导,因为转置可能是我想要完成的错误词。我愿意接受建议。


我有两个表,tblBase和tblLinks。 tblLinks包含tblBase中记录的URL。下图显示了这些表的基本版本和关系。

Relationship

tblBase

tblBaseID
Title

tblLinks

tblLinksID
tblBaseIDFK
LinkURL

我希望开发一个查询或报告,它将显示tblBase中的记录以及一种平面表中的所有相关链接。这是一个例子:

tblBase:

tblBase Sample Data

tblBaseID---Title
1-----------ABC
2-----------DEF
3-----------HIJ

tblLinks:

tblLinks Sample Data

tblLinksID---tblBaseIDFK---LinkURL
1------------1-------------ABCLink1
2------------1-------------ABCLink2
3------------2-------------DEFLink1
4------------2-------------DEFLink2
5------------2-------------DEFLink3

这是我正在寻找的最终结果,基于样本数据:

Result

理想情况下,我希望能够使用查询创建它,但我不知道这是否可行。作为最后的手段,我可​​以编写VBA来填充一些临时表并浏览tblLinks中的每条记录,将数据放在适当的位置。如果无法进行查询,也许有一个更好的解决方案,而不是有人可以指向我的临时表。

谢谢。

1 个答案:

答案 0 :(得分:1)

我建议2种不同的选择。

第一个选项:静态查询,这个选项的优点是容易,但缺点是tblBase中每次重新链接N个链接是静态的

SELECT B.tblBaseID
     , B.Title
     , MAX(IIF( L.BaseIdRank = 1, L.LinkURL, '')) AS Link1
     , MAX(IIF( L.BaseIdRank = 2, L.LinkURL, '')) AS Link2
     , MAX(IIF( L.BaseIdRank = 3, L.LinkURL, '')) AS Link3
FROM   tblBase AS B
    LEFT JOIN
       (SELECT L1.tblLinksID
             , L1.tblBaseIDFK
             , L1.LinkURL
             , COUNT(*) AS BaseIdRank
        FROM   tblLinks AS L1
            INNER JOIN
               tblLinks AS L2
               ON  L1.tblLinksID >= L2.tblLinksID
               AND L1.tblBaseIDFK = L2.tblBaseIDFK
        GROUP BY L1.tblLinksID
             , L1.tblBaseIDFK
             , L1.LinkURL
       ) AS L
       ON B.tblBaseID = L.tblBaseIDFK
GROUP BY B.tblBaseID, B.Title;

这是结果表

enter image description here

第二个选项:优点是这个选项是使用dinamic数量的链接可以正常工作,缺点是你需要在一个模块中创建一个函数。

步骤1。在模块中创建以下功能

Public Function createLinksByBase() As String
    On Error Resume Next

    ' Delete resulting table if it exists
    CurrentDb.Execute "DROP TABLE tblLinksByBase"

    ' Variables
    Dim nMaxLinks As Integer
    Dim i As Integer
    Dim sSQL As String

    ' Get max number of links
    sSQL = "SELECT MAX(links) AS max_links " & _
           "FROM  (SELECT  tblBaseIDFK " & _
           "             , COUNT(*) AS links " & _
           "       FROM tblLinks " & _
           "       GROUP BY tblBaseIDFK " & _
           "       ) L"
    nMaxLinks = CurrentDb.OpenRecordset(sSQL)!max_links

    ' Prepare query for generate table
    sSQL = ""
    For i = 1 To nMaxLinks
        sSQL = sSQL & " , MAX(IIF( L.BaseIdRank = " & i & ", L.LinkURL, '')) AS Link" & i & " "
    Next i
    sSQL = "SELECT B.tblBaseID " & _
           "     , B.Title " & _
           sSQL & _
           "INTO   tblLinksByBase " & _
           "FROM   tblBase AS B " & _
           "    LEFT JOIN  " & _
           "       (SELECT L1.tblLinksID " & _
           "             , L1.tblBaseIDFK " & _
           "             , L1.LinkURL " & _
           "             , COUNT(*) AS BaseIdRank " & _
           "        FROM   tblLinks AS L1 " & _
           "            INNER JOIN " & _
           "               tblLinks AS L2 " & _
           "               ON  L1.tblLinksID >= L2.tblLinksID " & _
           "               AND L1.tblBaseIDFK = L2.tblBaseIDFK " & _
           "        GROUP BY L1.tblLinksID " & _
           "             , L1.tblBaseIDFK " & _
           "             , L1.LinkURL " & _
           "       ) AS L " & _
           "       ON B.tblBaseID = L.tblBaseIDFK " & _
           "GROUP BY B.tblBaseID, B.Title"

    ' Create resulting table
    CurrentDb.Execute (sSQL)

    createLinksByBase = "Ready"
End Function

步骤2:调用该函数,例如,您可以使用此

创建视图
 SELECT createLinksByBase() AS status

每次运行查询时,都会创建/刷新表“tblLinksByBase”

enter image description here

我希望这些选项可以帮助你