需要对列A进行重复数据删除并列出同一行中B列的可能值

时间:2016-01-08 22:08:39

标签: sql-server one-to-many transpose

我正在使用SQL Server 2014.我有一个包含两个列的表(称为列A和列B),其中包含字母数字字符的数据。列A和列B之间存在一对多的关系。我想重新配置表以列出A列中的每个唯一值,并将相关值从列B转换为列B,C,D等等。

即。转过来:

 Column A | Column B
  A1          A2
  A1          A3
  B1          B2
  C1          C2
  C1          C3
  C1          C4

进入这个:

Column A |  Column B |  Column C |  Column D
 A1            A2          A3   
 B1            B2       
 C1            C2          C3         C4

我正在使用的表有A列和B列的数千个可能值,但是,A列中的任何给定值在B列中最多只有4个相关值。

非常感谢任何对以前回答的问题的帮助或参考。

谢谢,

2 个答案:

答案 0 :(得分:0)

您可以使用以下一组查询来执行此操作。

您需要先创建一个名为newTable的适当表,以包含新的值集。

因为您已经提到Column A中的每个值在Column B中最多只有4个不同的值,所以您应该为columnA值创建一个ColA的新表,并且还有四列名为ColB,ColC,ColD,ColE的列,其中包含原始表格中ColumnB下的四个不同值。

我使用CTE即公共表表达式对每个columnA值下的每个不同值进行序列编号,以便序列#1值进入ColB,序列#2进入ColC,依此类推。每个不同ColumnA值中的序列号在下面的T-SQL代码中称为RowNum

这完全有效,因为我在根据您的要求创建的数据集上测试了它。在运行newTable查询之前,请确保表CREATE TABLE不存在。

从原始表格中创建/填充新表格的T-SQL

--create new table if it does not exist else delete all rows
IF OBJECT_ID(N'newTable', N'U') IS NULL
BEGIN
    CREATE TABLE newTable
    (
                 ColA varchar(50), ColB varchar(50), ColC varchar(50), ColD varchar(50), ColE varchar(50)
    );
END;
ELSE
BEGIN
    DELETE FROM newTable;
END;

--populate first column in new table
INSERT INTO newTable( ColA )
       SELECT DISTINCT ColumnA
       FROM Table1;

--populate remaining columns in new table
WITH cte
     AS (SELECT t.ColumnA, t.ColumnB,
     ROW_NUMBER() OVER(PARTITION BY t.ColumnA ORDER BY t.ColumnB) AS RowNum
         FROM dbo.Table1 AS t)
     UPDATE dbo.newTable
       SET dbo.newTable.ColB =
     (
         SELECT ColumnB
         FROM cte
         WHERE cte.RowNum = 1 AND
               cte.ColumnA = dbo.newTable.ColA
     ), dbo.newTable.ColC =
     (
         SELECT ColumnB
         FROM cte
         WHERE cte.RowNum = 2 AND
               cte.ColumnA = dbo.newTable.ColA
     ), dbo.newTable.ColD =
     (
         SELECT ColumnB
         FROM cte
         WHERE cte.RowNum = 3 AND
               cte.ColumnA = dbo.newTable.ColA
     ), dbo.newTable.ColE =
     (
         SELECT ColumnB
         FROM cte
         WHERE cte.RowNum = 4 AND
               cte.ColumnA = dbo.newTable.ColA
     );

答案 1 :(得分:0)

您需要:a)ROW_NUMBER()col_b over col_a,b)PIVOT结果

这可以随意使用:

#include <iostream>
#include <cstdlib>
#include <math.h>

using namespace std;

struct DynArrayQueue{
    int front, rear;
    int capacity;
    int* array;
};

void ResizeQueue(struct DynArrayQueue* Q);

struct DynArrayQueue* CreateDynQueue(){

    struct DynArrayQueue* Q = (struct DynArrayQueue* )malloc(sizeof(struct DynArrayQueue));

    if(!Q)
    {
        cout << "Memory Error in allocation!\n";
        return NULL;
    }

    Q->capacity = 1;
    Q->front = Q->rear = -1;
    Q->array = (int* )malloc(Q->capacity * sizeof(int));

    if(!Q->array)
     {
         cout << "Memory error in creating queue!\n";
         return NULL;
     }

    return Q;
}

int IsEmptyQueue(struct DynArrayQueue* Q){
    if(Q->front == -1){
        cout << "Queue is empty!\n";
        return 1;
    }
    else{
        cout << "Queue not empty\n";
        return 0;
    }
}

int IsFullQueue(struct DynArrayQueue* Q){
    if((((Q->rear)+1)%Q->capacity) == Q->front)
    {
        cout << "Queue is full!\n";
        return 1;
    }else{
        cout << "Queue not full!\n";
        return 0;
    }
}

void QueueSize(struct DynArrayQueue* Q){
    int s;
    s = (Q->capacity - Q->front + Q->rear + 1) % Q->capacity;
    cout << "Size of the queue is " << s;
    cout << "\n\n";
}

void EnQueue(struct DynArrayQueue* Q){
    int data;
    cout << "Enter the data to be inserted:\n";
    cin >> data;
    if(IsFullQueue(Q))
      {
          ResizeQueue(Q);
      }
    Q->rear = (Q->rear + 1)%Q->capacity;
    Q->array[Q->rear] = data;
    if(Q->front == -1)
    {
        Q->front = Q->rear;
    }
}

void ResizeQueue(struct DynArrayQueue* Q){
    int size = Q->capacity;
    Q->capacity = Q->capacity * 2;
    Q->array = (int* )realloc(Q->array, Q->capacity);
    if(!Q->array)
          cout << "Memory error!\n";
    if(Q->front > Q->rear)
    {
        for(int i = 0; i < Q->front; i++)
        {
            Q->array[i+size] = Q->array[i];
        }
        Q->rear = Q->rear + size;
    }
}

void DeQueue(struct DynArrayQueue* Q){    **this function does not work properly**
    int data = 0;
    if(IsEmptyQueue(Q))
    {
        cout << "Queue Underflow!\n";
        cout << "No element to delete!\n";
    }
    else{
        data = Q->array[Q->front];
        if(Q->front == Q->rear)
        {
            Q->front = Q->rear = -1;
        }
        else
        {
            Q->front = ((Q->front) + 1) % Q->capacity;
        }
    }
    cout << "Element deleted is " << data;
    cout << "\n";
}

void DeleteQueue(struct DynArrayQueue* Q){
    if(Q){
        if(Q->array)
        {
            free(Q->array);
        }
        free(Q);
    }
}

int main()
{
    int choice;
    struct DynArrayQueue* Q1;
    while(1)
    {
        cout << "1. Press to create a Queue:\n";
        cout << "2. Enter an element in the queue:\n";
        cout << "3. Delete an element from the queue:\n";
        cout << "4. Press to know the Queue size:\n";
        cout << "5. Press to know if Queue is full:\n";
        cout << "6. Press to know if Queue is empty:\n";
        cout << "7. Press enter to exit:\n";
        cout << "Enter your choice:\n";
        cin >> choice;
        switch(choice)
        {
        case 1:
            Q1 = CreateDynQueue();
            break;
        case 2:
            EnQueue(Q1);
            break;
        case 3:
            DeQueue(Q1);
            break;
        case 4:
            QueueSize(Q1);
            break;
        case 5:
            IsFullQueue(Q1);
            break;
        case 6:
            IsEmptyQueue(Q1);
            break;
        case 7:
            exit(0);
            break;
        default:
            cout << "Wrong choice entered!\n";
            break;
        }
    }
    DeleteQueue(Q1);
}