Call function for specifying columns in SQL TRANSFORM query

后端 未结 5 1562
情歌与酒
情歌与酒 2020-12-21 05:33

Here is my query:

PARAMETERS ...
TRANSFORM ...
SELECT ...
...
PIVOT Mytable.type In (\"Other\",\"Info\");

This is a cross query and I need

5条回答
  •  被撕碎了的回忆
    2020-12-21 05:59

    If the IN list is excluded from the PIVOT clause, the TRANSFORM query automatically creates columns for every PIVOT value generated from the SELECT statement. The final columns can be filtered by specifying the IN expression with "hard-coded" (i.e. literal) values. That is of course known from the other answers.

    The exact same effect can be achieved by limiting the data from the SELECT query to start with... before the TRANSFORM needs to filter it. In this way, one is not limited to only pre-defined literal values--rather combinations of JOINS, sub-queries and/or VBA functions can also pre-filter the data, effectively choosing which columns appear in the transform table. Note that the HAVING clause is not allowed in a TRANSFORM query, but it could be used in another query which the TRANSFORM then selects on, so there are effectively no limits to how the data is prepared before the TRANSFORM.

    All of the following produce equivalent results. First using PIVOT...IN:

    TRANSFORM Count(Services.ID) AS [Schedules]
    SELECT Agreement.City FROM Agreement INNER JOIN Services ON Agreement.Account = Services.Account
    WHERE ( Services.Code = "IS" )
    GROUP BY Agreement.City ORDER BY Agreement.City
    PIVOT Month([ServiceDate]) In (1,4,12)
    

    Using IN operator in WHERE clause:

    TRANSFORM Count(Services.ID) AS [Schedules]
    SELECT Agreement.City FROM Agreement INNER JOIN Services ON Agreement.Account = Services.Account
    WHERE ( (Month([ServiceDate]) In (1,4,12)) AND Services.Code = "IS" )
    GROUP BY Agreement.City ORDER BY Agreement.City
    PIVOT Month([ServiceDate])
    

    but unlike the PIVOT...IN clause, the list can also be another query:

    WHERE ((Month([ServiceDate]) In (SELECT Values FROM PivotValues)) AND Services.Code = "IS" )
    

    Finally, using a VBA function (which answers the original question):

    TRANSFORM Count(Services.ID) AS [Schedules]
    SELECT Agreement.City FROM Agreement INNER JOIN Services ON Agreement.Account = Services.Account
    WHERE ( ReportMonth([ServiceDate]) AND Services.Code = "IS" )
    GROUP BY Agreement.City ORDER BY Agreement.City
    PIVOT Month([ServiceDate])
    

    With the VBA function defined in a standard module:

    Public Function ReportMonth(dt As Date) As Boolean
      Select Case Month(dt)
        Case 1, 4, 12: ReportMonth= True
        Case Else:     ReportMonth= False
      End Select
    End Function
    

    (iDevlop already suggested this solution in a comment, but I don't think it was understood and good examples are required.)

提交回复
热议问题