2012-07-21 117 views
0

我真的很难搞清楚如何将MS Access CrossTab查询转换为T-SQL,以便在SQL2000或Linq-to-SQL上运行。我有一个查询,看起来像这样在访问:SQL 2000 TSQL - 创建数据透视表

Access Cross Tab Query 并产生这样的:通过项目ID和STOREID Access Cross Tab Query Results

查询基本上团体和总结的数量出售,但在Access中的交叉表查询,我可以为每个行都有一个唯一的ItemID,每个StoreID都有一个列,并且每个StoreID/ItemID组合的总数量为该值。

你如何在T-SQL 2000中构建这个?我可以使用分组构建一个简单的选择查询,但它会为我提供三列数据,即StoreID,ItemID和Qty。但我需要的是一个项目ID列,并在结果每STOREID一列设置

SELECT  Trans.TranSID as StoreID, TransDetail.TranItemID as ItemID, SUM(TransDetail.Qty) AS TotalQtyForStore 
    FROM   Trans INNER JOIN 
          TransDetail ON Trans.TranID = TransDetail.TranID INNER JOIN 
          Item ON TransDetail.TranItemID = Item.ItemID 
    WHERE  (Trans.TranDate > CONVERT(DATETIME, '2005-01-01 00:00:00', 102)) AND (Trans.TranTypeID = 'so' OR 
          Trans.TranTypeID = 'ca') AND (Trans.TranStatus <> 'v') AND (Item.ItemClassID = 'RHM') 
    GROUP BY Trans.TranSID, TransDetail.TranItemID 

将会产生这样的:

enter image description here

但我真正需要做的是改变这个数据以便StoreID值成为列,就像上面的Access CrossTab查询一样。

+0

我通常不会在SQL中这样做,我会在我使用的任何报告工具中执行交叉选项卡。例如,使用报告服务相对简单。 – Bert 2012-07-21 16:24:00

+0

我同意。它让我坚信,在Access中需要2秒钟的时间,但我无法在T-SQL或Linq-to-SQL中找到它。 – 2012-07-21 16:53:11

回答

0

我会这样做的动态SQL,因为你可能不提前知道所有的商店(TranSID)值。该存储过程将开始/结束日期作为参数,并生成一个交叉表。你也可以参数化一些其他的东西,比如TranStatus和ItemClassID,但是不清楚它们是否是你的查询中的固定或可变元素。

CREATE PROCEDURE dbo.CrossTabByItem 
    @StartDate DATETIME, 
    @EndDate DATETIME = NULL 
AS 
BEGIN 
    SET NOCOUNT ON; 

    SET @EndDate = COALESCE(DATEADD(DAY, 1, @EndDate), GETDATE()); 

    DECLARE @sql NVARCHAR(4000); SET @sql = N''; 

    SELECT @sql = @sql + ', 
    [' + TranSID + '] = SUM(CASE WHEN t.TranSID = ''' 
    + TranSID + ''' THEN td.Qty ELSE 0 END)' FROM 
    (
     SELECT DISTINCT TranSID FROM dbo.Trans 
     WHERE TranDate >= @StartDate AND TranDate < @EndDate 
    ) AS x ORDER BY TranSID; 

    SET @sql = N'SELECT ItemID = td.TranItemID' + @sql + ' 
     FROM dbo.Trans AS t 
     INNER JOIN dbo.TransDetail AS td 
     ON t.TranID = td.TranID 
     INNER JOIN dbo.Item AS i 
     ON td.TranItemID = i.ItemID 
     WHERE t.TranDate >= @StartDate 
     AND t.TranDate < @EndDate 
     AND t.TranTypeID IN (''so'',''ca'') 
     AND t.TranStatus <> ''v'' 
     AND i.ItemClassID = ''RHM'' 
     GROUP BY td.TranItemID;'; 

    EXEC sp_executesql @sql, 
     N'@StartDate DATETIME, @EndDate DATETIME', 
     @StartDate, @EndDate; 
END 
GO 

所以,你可以这样调用,获得了从2005年1月1日到现在:

EXEC dbo.CrossTabByItem @StartDate = '20050101'; 

或者这样,得到的只是2005年1月的:

EXEC dbo.CrossTabByItem @StartDate = '20050101', @EndDate = '20050131'; 
+0

我创建了存储过程并按原样运行,但出现错误:“关键字'GROUP'附近的语法错误” – 2012-07-21 16:46:30

+0

对不起,您所有不必要的括号都会导致我的粗心错字。请现在尝试。 – 2012-07-21 16:49:00

+0

Bam!就是这样。我惊呆了,谦虚。我将参数化ClassID,这将是很好的去。太感谢了!!! – 2012-07-21 17:00:14