【问题标题】:Convert an Access crosstab query to T-SQL (SQL Server)将 Access 交叉表查询转换为 T-SQL (SQL Server)
【发布时间】:2013-10-24 23:50:00
【问题描述】:

我在 Access 中有以下交叉表查询:

Transform Count(1) as Count
Select Cust,[Cust#],EntryDate,CloseDate
from Tbl1,Dates
where EntryDate>=[start date]
Group by Cust,[Cust#],EntryDate,CloseDate
Order by EntryDate
Pivot Quote;

我很难将它转换为 T-SQL。 我是否应该使用 SSIS 进行枢轴转换来解决这个问题, 或者我们是否有一个等效的 SQL Server 查询?

【问题讨论】:

  • 这是Access中的参数查询吗?换句话说,当您在 Access 中运行查询时,它是否会提示用户输入任何值(可能是 [开始日期])?
  • 据我所知,查询中没有指定参数,主要目的是将此脚本转换为 T-Sql,但我无法理解其逻辑
  • 显示表中数据的示例和生成的交叉表数据可能更容易。但是交叉表是个坏消息,因为它们有动态列,而 T-SQL 或 SSIS 都不是这样。

标签: tsql ms-access ssis pivot


【解决方案1】:

我们确实没有足够的信息来转换特定的交叉表查询,所以这里有一个简单的示例可以帮助您实现目标:

对于名为 [Vehicles] 的表,其中包含...

VehicleID  VehicleMake  VehicleModel  VehicleType 
---------  -----------  ------------  ------------
        1  Ford         Focus         Compact car 
        2  Ford         F-150         Pickup truck
        3  Dodge        RAM 1500      Pickup truck
        4  Toyota       Tundra        Pickup truck
        5  Toyota       Prius         Hybrid car  
        6  Toyota       Tacoma        Pickup truck

...Access 交叉表查询...

TRANSFORM Count(Vehicles.VehicleID) AS CountOfVehicleID
SELECT Vehicles.VehicleType
FROM Vehicles
GROUP BY Vehicles.VehicleType
PIVOT Vehicles.VehicleMake;

...返回:

VehicleType   Dodge  Ford  Toyota
------------  -----  ----  ------
Compact car             1        
Hybrid car                      1
Pickup truck      1     1       2

下面的 T-SQL 脚本完成同样的事情

DECLARE 
        @ColumnList AS NVARCHAR(MAX),
        @SQL AS NVARCHAR(MAX)

-- build the list of column names based on the current contents of the table
--     e.g., '[Dodge],[Ford],[Toyota]'
--     required by PIVOT ... IN below
--     ref: http://stackoverflow.com/a/14797796/2144390     
SET @ColumnList = 
        STUFF(
            (
                SELECT DISTINCT ',' + QUOTENAME([VehicleMake])
                FROM [Vehicles] 
                FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'), 
            1, 
            1, 
            '')
SET @SQL = '
        WITH rollup
        AS
        (
            SELECT VehicleMake, VehicleType, COUNT(VehicleID) AS n FROM [Vehicles]
            GROUP BY VehicleMake, VehicleType
        )
        SELECT * FROM rollup
        PIVOT (SUM([n]) FOR [VehicleMake] IN (' + @ColumnList + ')) AS Results'
EXECUTE(@SQL)

返回:

VehicleType   Dodge  Ford  Toyota
------------  -----  ----  ------
Compact car    NULL     1    NULL
Hybrid car     NULL  NULL       1
Pickup truck      1     1       2

【讨论】:

  • 请添加一些关于动态 SQL 问题的 cmets 以及您提供的代码首先必须是动态的原因。就个人而言,我更喜欢通用的旋转存储过程,而不是每次都重写的自定义代码。你能提供其中之一吗?
【解决方案2】:
drop table #tmpT1
select distinct UserField2 into #tmpT1 from CreateExcelForm
--select * from #tmpT1
DECLARE @PivotColumnHeaders VARCHAR(MAX)
SELECT @PivotColumnHeaders = 
COALESCE(
@PivotColumnHeaders + ',[' + cast(UserField2 as varchar) + ']',
'[' + cast(UserField2 as varchar)+ ']'
)
FROM #tmpT1
print(@PivotColumnHeaders)
DECLARE @PivotTableSQL NVARCHAR(MAX)
SET @PivotTableSQL = N'
SELECT *
FROM (
SELECT
* from CreateExcelForm
) AS PivotData
PIVOT (
max(StockCode)
FOR UserField2 IN (
' + @PivotColumnHeaders + '
)
) AS PivotTable
'

EXECUTE(@PivotTableSQL)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-14
    • 2019-07-25
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多