使用select query / pivot从表数据构建字符串

时间:2014-01-22 10:18:02

标签: sql sql-server pivot

我有一张包含以下格式数据的表格。月份计数数据在最后3列中提供。

Rep_Name   months  year  checkin hours teamsize
--------------------------------------------------------- 
aaa_aaaurf  4      2013     184  3      3
aaa_aaaurf  8      2013     0    3      1
aaa_access  11     2013     10   27     11
aaa_access  12     2013     12   12     11

我需要构建一个类似于下面的字符串

Name :aaa_aaaurf,
Checkins:[[1,0],[2,0],[3,0],[4,3],[5,0],[6,0],[7,0],[8,3],[9,0],[10,0],[11,0],[12,0]],
hours:[[1,0],[2,0],[3,0],[4,184],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0],[12,0]],
teamsize:[[1,0],[2,0],[3,0],[4,3],[5,0],[6,0],[7,0],[8,3],[9,0],[10,0],[11,0],[12,0]]

此字符串仅适用于2013年,rep_name为aaa_aaaurf。我需要它每年复制每个rep_name。在这种情况下可以使用枢轴吗?或者我应该使用for循环来构建这样的字符串?

1 个答案:

答案 0 :(得分:3)

注意@AaronBertrand的话。

作为一个彻头彻尾的白痴,尽管我试图向他们解释数据库用于存储well-structured数据,但我已经屈服于懒惰的应用程序开发人员抱怨请求在数据库端处理这种无意义的事情。并且无论如何都不是特别擅长字符串包装。你在这里尝试做的是使数据库依赖于应用程序的第一步,并且通常考虑到整个板块的不良形式,导致存储的数据不再在原始应用程序之外可用(因此,没有报告并且非常非常迅速地成为一个完整的维护噩梦。

如果有机会,你正在为自己这样做,并且这绝不会让T-SQL成为生产环境的遗憾,这里有一个如何的例子这样做:

IF NOT EXISTS ( SELECT  1
                FROM    sys.objects
                WHERE   name = 't_Pack' 
                    AND type = 'U' )
BEGIN
    --DROP TABLE dbo.t_Pack;
    CREATE TABLE dbo.t_Pack
    (
        Rep_Name        VARCHAR( 16 ),
        months          INTEGER,
        year            INTEGER,
        checkin         INTEGER,
        hours           INTEGER,
        teamsize        INTEGER
    );

    INSERT INTO dbo.t_Pack ( Rep_Name, months, year, checkin, hours, teamsize )
    SELECT  Rep_Name, months, year, checkin, hours, teamsize
    FROM (      SELECT  Rep_Name = NULL, 
                        months = NULL, 
                        year = NULL, 
                        checkin = NULL, 
                        hours = NULL, 
                        teamsize = NULL 
    UNION ALL   SELECT  'aaa_aaaurf', 4, 2013, 184, 3, 3
    UNION ALL   SELECT  'aaa_aaaurf', 8, 2013, 0, 3, 1
    UNION ALL   SELECT  'aaa_access', 11, 2013, 10, 27, 11
    UNION ALL   SELECT  'aaa_access', 12, 2013, 12, 12, 11 ) l
    WHERE   Rep_Name IS NOT NULL;
END;
GO

DECLARE @RepName        VARCHAR( 16 ),
        @CheckInString  VARCHAR( MAX ),
        @HoursString    VARCHAR( MAX ),
        @TeamSizeString VARCHAR( MAX ),
        @FinalString    VARCHAR( MAX );
    SET @RepName = 'aaa_aaaurf';

DECLARE @t_Months       TABLE
(
    MonthID             TINYINT
);

INSERT INTO @t_Months( MonthID )
VALUES ( 1 ), ( 2 ), ( 3 ), ( 4 ), ( 5 ), ( 6 ), ( 7 ), ( 8 ), ( 9 ), ( 10 ), ( 11 ), ( 12 );

SELECT  @CheckInString = ISNULL( @CheckInString, 'Checkins:[' )
            + '[' + LEFT( mth.MonthID, 10 ) + ',' + LEFT( ISNULL( p.checkin, 0 ), 10 ) + '],',
        @HoursString = ISNULL( @HoursString, 'hours:[' )
            + '[' + LEFT( mth.MonthID, 10 ) + ',' + LEFT( ISNULL( p.hours, 0 ), 10 ) + '],',
        @TeamSizeString = ISNULL( @TeamSizeString, 'teamsize:[' )
            + '[' + LEFT( mth.MonthID, 10 ) + ',' + LEFT( ISNULL( p.teamsize, 0 ), 10 ) + '],'
FROM    @t_Months mth
LEFT JOIN dbo.t_Pack p
    ON  mth.MonthID = p.months
    AND p.Rep_Name = @RepName
ORDER BY mth.MonthID;

    SET @FinalString = 'Name:' + @RepName + ',' + CHAR( 10 )
            + LEFT( @CheckInString, LEN( @CheckInString ) - 1 ) + '],' + CHAR( 10 )
            + LEFT( @HoursString, LEN( @HoursString ) - 1 ) + '],' + CHAR( 10 )
            + LEFT( @TeamSizeString, LEN( @TeamSizeString ) - 1 ) + ']';

PRINT   @FinalString;
GO

DROP TABLE dbo.t_Pack;
GO