将一些列转换为行

时间:2016-09-15 11:33:33

标签: sql sql-server transpose

我知道以前曾问过同样的问题。但是,我没有成功做我需要做的事情。所以我问你。

我有一个包含client_ID的表,以及购买与每个客户相对应的不同产品类别的一些概率。

Client_ID | Prob_CategoryA | Prob_CategoryB | Prob_CategoryC

     1                 0.2                  0.3                    0.2
     2                 0.4                  0.6                    0.7
     3                 0.3                  0.7                    0.4

现在我想做的是将上表转换成这个。

Client_ID | Category Name |  Probability

   1                A               0.2
   1                B               0.3 
   1                C               0.2
   2                A               0.4
   2                B               0.6
   2                C               0.7
   3                A               0.3
   3                B               0.7
   3                C               0.4

非常感谢

3 个答案:

答案 0 :(得分:2)

简单的UNPIVOT:

SELECT Client_Id, SUBSTRING(Cat, 14, 1) [Category Name], Probability
FROM Src
UNPIVOT (Probability FOR Cat IN (Prob_CategoryA, Prob_CategoryB, Prob_CategoryC)) UP

<强>结果

Client_Id   Category Name Probability
----------- ------------- -----------
1           A             0.2
1           B             0.3
1           C             0.2
2           A             0.4
2           B             0.6
2           C             0.7
3           A             0.3
3           B             0.7
3           C             0.4

答案 1 :(得分:0)

使用UNPIVOT

SELECT Client_ID, Cats, Probability
FROM
(SELECT Client_ID, Prob_CategoryA, Prob_CategoryB, Prob_CategoryC
 FROM yourTable) t
UNPIVOT
(Probability FOR Cats IN (Prob_CategoryA, Prob_CategoryB, Prob_CategoryC)
) AS c

答案 2 :(得分:0)

除了Unpivot(见其他答案),还有UNION。

#include <iostream>
#include "zlib-1.2.8/zlib.h"
#include <stdexcept>
#include <iomanip>
#include <sstream>
#include <stdio.h>
#include <assert.h>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include "zlib.h"
#include "zconf.h"

#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
#  include <fcntl.h>
#  include <io.h>
#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
#  define SET_BINARY_MODE(file)
#endif

#define CHUNK 16384

using namespace std;

bool gzipInflate( const std::string& compressedBytes, std::string& uncompressedBytes ) {
    if ( compressedBytes.size() == 0 ) {
        uncompressedBytes = compressedBytes ;
        return true ;
    }

    uncompressedBytes.clear() ;

    unsigned full_length = compressedBytes.size() ;
    unsigned half_length = compressedBytes.size() / 2;

    unsigned uncompLength = full_length ;
    char* uncomp = (char*) calloc( sizeof(char), uncompLength );

    z_stream strm;
    strm.next_in = (Bytef *) compressedBytes.c_str();
    strm.avail_in = compressedBytes.size() ;
    strm.total_out = 0;
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;

    bool done = false ;

    if (inflateInit2(&strm, (16+MAX_WBITS)) != Z_OK) {
        free( uncomp );
        return false;
    }

    while (!done) {
        // If our output buffer is too small
        if (strm.total_out >= uncompLength ) {
            // Increase size of output buffer
            char* uncomp2 = (char*) calloc( sizeof(char), uncompLength + half_length );
            memcpy( uncomp2, uncomp, uncompLength );
            uncompLength += half_length ;
            free( uncomp );
            uncomp = uncomp2 ;
        }

        strm.next_out = (Bytef *) (uncomp + strm.total_out);
        strm.avail_out = uncompLength - strm.total_out;

        // Inflate another chunk.
        int err = inflate (&strm, Z_SYNC_FLUSH);
        if (err == Z_STREAM_END) done = true;
        else if (err != Z_OK)  {
            break;
        }
    }

    if (inflateEnd (&strm) != Z_OK) {
        free( uncomp );
        return false;
    }

    for ( size_t i=0; i<strm.total_out; ++i ) {
        uncompressedBytes += uncomp[ i ];
    }
    free( uncomp );
    return true ;
}



/** Compress a STL string using zlib with given compression level and return
 * the binary data. */
std::string compress_string(const std::string& str, int compressionlevel = Z_BEST_COMPRESSION)
{
    z_stream zs;                        // z_stream is zlib's control structure
    memset(&zs, 0, sizeof(zs));

    if (deflateInit(&zs, compressionlevel) != Z_OK)
        throw(std::runtime_error("deflateInit failed while compressing."));

    zs.next_in = (Bytef*)str.data();
    zs.avail_in = str.size();           // set the z_stream's input

    int ret;
    char outbuffer[32768];
    std::string outstring;

    // retrieve the compressed bytes blockwise
    do {
        zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
        zs.avail_out = sizeof(outbuffer);

        ret = deflate(&zs, Z_FINISH);

        if (outstring.size() < zs.total_out) {
            // append the block to the output string
            outstring.append(outbuffer,zs.total_out - outstring.size());
        }
    }
    while (ret == Z_OK);

    deflateEnd(&zs);

    if (ret != Z_STREAM_END) {          // an error occurred that was not EOF
        std::ostringstream oss;
        oss << "Exception during zlib compression: (" << ret << ") " << zs.msg;
        throw(std::runtime_error(oss.str()));
    }

    return outstring;
}


/* Reads a file into memory. */
bool loadBinaryFile( const std::string& filename, std::string& contents ) {
    // Open the gzip file in binary mode
    FILE* f = fopen( filename.c_str(), "rb" );
    if ( f == NULL )
        return false ;

    // Clear existing bytes in output vector
    contents.clear();

    // Read all the bytes in the file
    int c = fgetc( f );
    while ( c != EOF ) {
        contents +=  (char) c ;
        c = fgetc( f );
    }
    fclose (f);

    return true ;
}


int main(int argc, char *argv[]) {
    // Read the gzip file data into memory
    std::string fileData ;
    if ( !loadBinaryFile( "myfilein.gz", fileData ) ) {
        printf( "Error loading input file." );
        return 0 ;
    }

    // Uncompress the file data
    std::string data ;
    if ( !gzipInflate( fileData, data ) ) {
        printf( "Error decompressing file." );  
        return 0 ;  
    }  

    // Print the data  
    printf( "Data: \"" );  
    for ( size_t i=0; i<data.size(); ++i ) {  
        printf( "%c", data[i] );
    }  
    printf ( "\"\n" );


    std::string outy;
    // Compress the file data
    outy = compress_string(data, 0);

    //Write the gzipped data to a file.
    FILE *handleWrite=fopen("myfileout.gz","wb");
    fwrite(outy,sizeof(outy),1,handleWrite);

    fclose(handleWrite);

    return 0;  
}

UNION会删除重复项,但由于该数据不应该重复,因此UNION ALL将比UNION快