PIVOT的结果为0/1真/假或其他二进制格式

时间:2013-06-24 11:16:31

标签: sql sql-server tsql pivot

我有一个数据透视查询,它返回每个客户每个类别返回的结果:

transaction_id  1       2       3       4       5       6       7
10-52927        NULL    NULL    NULL    NULL    NULL    NULL    NULL
10-52928        NULL    NULL    NULL    NULL    NULL    NULL    NULL
10-52929        8       NULL    NULL    NULL    NULL    149     NULL
10-52930        NULL    NULL    NULL    NULL    NULL    NULL    NULL
10-52931        NULL    NULL    NULL    NULL    NULL    NULL    NULL
10-52932        NULL    NULL    12      NULL    NULL    NULL    NULL
10-52934        NULL    NULL    NULL    NULL    NULL    NULL    NULL
10-52935        NULL    NULL    NULL    NULL    NULL    33      NULL
10-52936        NULL    NULL    NULL    NULL    NULL    NULL    NULL

Pivot基于多条线路汇总从产品级别到类别的销售,这意味着每个transaction_id记录通常使用sum()作为枢轴参数从20多行汇总。

我想要实现的是以0-1格式获得结果,表明客户是否购买了1,2,3,4,5 ......〜400类的任何内容而不创建额外的表格,因为操作必须是重复了100多家商店。

有关如何执行此任务而不创建其他表来存储和更新结果的建议吗?

提前致谢。

编辑:

查询产品显示输出如下:

select transaction_id, [1], [2], [3], // up to ~400 numerical categories
from (SELECT  [transaction_id]
             ,[category]
             ,sum([SUM]) as SUM_2
      FROM [XXX].[dbo].[receipts]
      left join // join of recept table with category table
      where // store type related parametrs
      group by transaction_id, category) p 
PIVOT (sum([sum_2]) for [category] in
       ([1], [2], [3], [4], ... ) // shortened list of categories in order to improve code readability
      ) as pvt 
ORDER BY pvt.transaction_id

类别

3 个答案:

答案 0 :(得分:0)

好的,你可以在不改变cte(FROM部分)的情况下做到这一点。

在SELECT和FROM add

之间
INTO #MyTempTable

更安全的是事先创建它,检查它是否已经存在,并从现有的SELECT中插入。

然后你可以这样做:

SELECT transaction_id, CASE WHEN [1] IS NULL THEN 0 ELSE 1 END [1], 
-- repeat each case
FROM #MyTempTable

如果您可以更改CTE,请删除分组和汇总[SUM_v2],并始终将其值设为1。在PIVOT中将SUM更改为MIN

然后可以更简单的方式检查表格中的列:ISNULL([1], 0) [1]

答案 1 :(得分:0)

这实际上是一个非常有趣的问题。这是第二个解决方案,我获得组的交叉积和传播列ID,以便始终存在值。我可以想象这种方法存在性能损失。

我使用@Mark Ba​​nnister使用SIGN在0/1列中生成1。

;WITH P AS
(
   SELECT 
      IDS.transaction_id, IDS.category, CAST(ISNULL(SIGN(C.Sum), 0) AS INT) [hassum]
   FROM 
      (SELECT DISTINCT
      A.transaction_id, B.category
      FROM Reciepts [A] CROSS JOIN Categories [B]) AS IDS
      LEFT JOIN Transaction AS T ON T.transaction_id = IDS.transaction_ID
      LEFT JOIN Category AS C ON -- some unspecified join ...
          AND C.Category = IDS.Category
)
SELECT transaction_id, [1], [2], [3]
FROM P
PIVOT (MIN(hassum) FOR category IN ([1], [2], [3]) ) AS [hassum]

答案 2 :(得分:0)

如果您可以对源表进行分组,那么将有0或1个匹配的行,那么使用COUNT(类别)应该有效。 (它适用于我类似但略有不同的情况)