SQL Server:使用分组进行透视

时间:2016-09-07 15:17:39

标签: sql-server tsql

我正在尝试使用一个查询来转移一些数据并且它工作正常,除了我注意到我们的应用程序开发下游的数据问题。我注意到的是,由于枢轴需要聚合函数,因此我必须达到最大值,所以它实际上是最大值而不考虑列不是明显相同。我是新手,所以我可能会为我想要的结果做错事。任何帮助或方向将不胜感激。

查询:

SELECT 
    @cols = STUFF((SELECT ',' + QUOTENAME(proto_name)
                   FROM #temp_rackplan
                   GROUP BY proto_name
                   ORDER BY proto_name
                   FOR XML PATH(''),TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET @query = 'SELECT
                  dept_catg_grp_desc AS [Category Group]
                  ,dept_category_desc AS [Category]
                  ,fineline_desc AS [Fineline]
                  ,Supplier
                  ,ty_cust_choice_qty AS [CC]
                  ,season_code AS [SC]
                  ,set_strategy_desc AS [Set Strategy]
                  ,ty_landed_cost_amt AS [Landed Cost]
                  ,ty_freight_factor_pct AS [FF%]
                  ,ty_cost_w_ff AS [Cost w/FF]
                  ,ty_retail_amt AS [Retail $]
                  ,mu_pct AS [MU%]
,in_store_wm_yr_wk_id AS [In Str Wk]
,ty_start_wm_yr_wk_id AS [Start Wk]
,ty_end_wm_yr_wk_id AS [End Wk]
,ty_md_wm_yr_wk_id AS [MD Wk]
,fixture_group_desc AS [Fixture]
,Brand
,' + @cols + 
'
FROM 
(
SELECT
    dept_catg_grp_desc
    ,dept_category_desc
    ,fineline_desc
    ,Supplier
    ,ty_cust_choice_qty
    ,season_code
    ,set_strategy_desc
    ,ty_landed_cost_amt
    ,ty_freight_factor_pct
    ,ty_cost_w_ff
    ,ty_retail_amt
    ,mu_pct
    ,in_store_wm_yr_wk_id
    ,ty_start_wm_yr_wk_id
    ,ty_end_wm_yr_wk_id
    ,ty_md_wm_yr_wk_id
    ,fixture_group_desc
    ,Brand
    ,proto_name
    ,trgt_rack_cnt
FROM
    #temp_rackplan
) AS x
PIVOT 
(
    MAX(trgt_rack_cnt)
    FOR proto_name in (' + @cols + ')
) AS p '

查询结果:

Catgrp  Category  Fineline  Set Strategy  Fixture  Proto A  Proto B  Proto C
----------------------------------------------------------------------------
SHOES   MENS      254       10-50         4WAY     2        1        1
SHOES   MENS      254       10-50         H-RACK   2        1        1
SHOES   MENS      254       60-90         4WAY     2        1        1
SHOES   MENS      254       60-90         H-RACK   2        1        1
SHOES   MENS      2920      10-50         4WAY     2        1        1
SHOES   MENS      2920      10-50         H-RACK   2        1        1
SHOES   MENS      2920      60-90         4WAY     2        1        1
SHOES   MENS      2920      60-90         H-RACK   2        1        1

期望的结果(匹配数据库):

Catgrp  Category  Fineline  Set Strategy  Fixture  Proto A  Proto B  Proto C
----------------------------------------------------------------------------
SHOES   MENS      254       10-50         4WAY     2        1        1
SHOES   MENS      254       10-50         H-RACK   1        1        1
SHOES   MENS      254       60-90         4WAY     1        1        1
SHOES   MENS      254       60-90         H-RACK   1        1        1
SHOES   MENS      2920      10-50         4WAY     1        1        1
SHOES   MENS      2920      10-50         H-RACK   1        1        1
SHOES   MENS      2920      60-90         4WAY     2        1        1
SHOES   MENS      2920      60-90         H-RACK   1        1        1

1 个答案:

答案 0 :(得分:0)

根据研究,我无法根据报告的要求使用枢轴功能。这是我创建的解决方法,输出正确的数据(草稿)

DECLARE @ps_id NVARCHAR(5) = 2519
DECLARE @cols NVARCHAR(MAX)
DECLARE @curproto NVARCHAR(50)
DECLARE @loopcnter INT = 0
DECLARE @protocnt INT = (SELECT DISTINCT COUNT(DISTINCT proto_name) FROM apparel_planning_reporting.dbo.Plan_Proto WHERE planning_session_id = @ps_id)
DECLARE @looptbl TABLE
(
id INT,
proto_name NVARCHAR(50)
)

CREATE TABLE #temploop(fineline INT, strategy_zone_group_cd INT)

--Insert initial records into proto table
INSERT INTO @looptbl
SELECT DISTINCT 0 AS id, proto_name FROM apparel_planning_reporting.dbo.Plan_Proto WHERE planning_session_id = @ps_id

--Generate record id
UPDATE @looptbl SET @loopcnter = id = @loopcnter + 1

DECLARE @sqlexe nvarchar(max)
--Loop to generate report
SET @loopcnter = 1
WHILE(@loopcnter <= @protocnt)
BEGIN
       SET @curproto = (SELECT proto_name FROM @looptbl WHERE id = @loopcnter)
       SET @sqlexe = 'ALTER TABLE #temploop ADD [' + @curproto + '] DECIMAL(18,2)'
       EXEC (@sqlexe)
       SET @sqlexe = 'INSERT INTO #temploop (fineline, strategy_zone_group_cd,['+@curproto+']) SELECT pras.fineline_nbr, pras.strategy_zone_group_cd, pras.trgt_rack_cnt FROM apparel_planning_reporting.dbo.Plan_Rack_Alloc_Store AS pras, apparel_planning_reporting.dbo.Plan_Proto AS pp WHERE COALESCE(pras.planning_session_id, pp.planning_session_id) =' + @ps_id + ' AND pras.str_collection_id = pp.plan_proto_id AND pp.proto_name = '''+@curproto+''' OPTION(MAXDOP 12)'
       EXEC (@sqlexe)
       SET @loopcnter = @loopcnter + 1
END
--SELECT * FROM #temploop

SELECT @cols = STUFF((
            SELECT ',MAX(' + QUOTENAME(proto_name) + ') AS ' + QUOTENAME(proto_name)
            FROM @looptbl
            GROUP BY proto_name
            ORDER BY proto_name
            FOR XML PATH('')
                ,TYPE
            ).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

SET @sqlexe = '
SELECT
    fineline
    ,strategy_zone_group_cd
    ,'+@cols+'
FROM #temploop
GROUP BY fineline, strategy_zone_group_cd
'
EXEC(@sqlexe)

drop table #temploop