Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL pivot表1转换为表2,而不使用动态SQL pivot或硬代码查询_Sql - Fatal编程技术网

SQL pivot表1转换为表2,而不使用动态SQL pivot或硬代码查询

SQL pivot表1转换为表2,而不使用动态SQL pivot或硬代码查询,sql,Sql,我已经看到了许多关于使用SQL数据透视表、使用动态SQL数据透视或使用CASE WHEN硬代码查询的问题和答案 然而,有没有什么方法可以不使用这2个数据透视表 表1: | col1 | col2 | col3 | |--------|-------|--------| | ABCD | 1 | XY123 | | ABCD | 2 | RT789 | | PQST | 3 | XY123 | | PQST | 4 | RT789

我已经看到了许多关于使用SQL数据透视表、使用动态SQL数据透视或使用
CASE WHEN
硬代码查询的问题和答案

然而,有没有什么方法可以不使用这2个数据透视表

表1:

| col1   | col2  | col3   |
|--------|-------|--------|
| ABCD   | 1     | XY123  |
| ABCD   | 2     | RT789  |
| PQST   | 3     | XY123  |
| PQST   | 4     | RT789  |
转向

| col1   | ABCD  | PQST  |
|--------|-------|-------|
| XY123  | 1     | 3     |
| RT789  | 2     | 4     |
我的想法是通过以下方式检索col的结构:

WITH
  structure AS (
    SELECT DISTINCT 
      col3 AS col1, col1 AS colName, col2 AS values
    FROM table1 ori
  )
然后用
连接
提取每个单元格的匹配值并临时存储。最后,
JOIN
再次在输出中填充它们。但是,在完成上述步骤后,我被卡住了。我无法使用PIVOT,必须动态执行此操作(即当出现时,无法使用该方法使用
CASE对每个值进行硬编码)

如何实现这一点?

这不像动态轴心那样高效(也不像编码那么容易)。然而,这是可行的

它确实需要是动态的,例如,将每个SQL语句创建为字符串并执行该字符串

这个过程包括

  • 确定列名(存储在临时表中)
  • 仅使用第一列创建表
  • 填充第一列
  • 对于每个附加列名
    • 向表中添加列(动态)
    • 用数据填充该列
您还没有指定数据库-下面我将使用SQL Server/t-SQL说明以下内容

下面是本文的内容,您可以看到发生了什么

CREATE TABLE #ColNames (ColNum int IDENTITY(1,1), ColName nvarchar(100), ColNametxt nvarchar(100));

INSERT INTO #ColNames (ColName, ColNametxt)
    SELECT DISTINCT QUOTENAME(Col1), Col1
    FROM table1;
这将使用值
1、[ABCD]、ABCD
2、[PQST]、PQST
填充#ColNames表

下一步是创建输出表——我称之为#pvttable

这将创建一个表,其中有一列(col1)的值
XY123
RT789

编写您喜爱的循环(例如,游标、while循环)。每一步

  • 获取下一个列名
  • 将列添加到表中
  • 用适当的数据更新该列
e、 例如,以下是您的数据的说明性示例

DECLARE @CustomSQL nvarchar(4000);
DECLARE @n int = 1;
DECLARE @ColName nvarchar(100);
DECLARE @ColNametxt nvarchar(100);

SELECT      @ColName = ColName,
            @ColNameTxt = ColNameTxt
    FROM    #ColNames 
    WHERE   ColNum = @n;

WHILE @ColName IS NOT NULL
    BEGIN

    SET @CustomSQL = N'ALTER TABLE #pvttable ADD ' + @ColName + N' nvarchar(100);';
    EXEC (@CustomSQL);

    SET @CustomSQL = 
        N'UPDATE #pvttable SET ' + @Colname + N' = table1.col2'
        + N' FROM #pvttable INNER JOIN table1 ON #pvttable.col1 = table1.col3'
        + N' WHERE table1.col1 = N''' + @ColNametxt + N''';';
    EXEC (@CustomSQL);

    SET @n += 1;

    SET @ColName = NULL;
    SET @ColNametxt = NULL;

    SELECT      @ColName = ColName,
                @ColNameTxt = ColNameTxt
        FROM    #ColNames 
        WHERE   ColNum = @n;

    END;

SELECT * FROM #pvttable;

您使用的是哪种DBMS产品?“SQL”只是一种查询语言,而不是特定数据库产品的名称。请为您正在使用的数据库产品添加。“不要动态地做,也不要静态地做(硬编码)”---好吧,有动态和静态,没有第三种选择,所以…谢谢你的反馈@a_horse_和_no_name!我将对此进行改进。@Andreas,可能会有一些混淆,我的意思是应该动态获取列,而不是使用“动态SQL pivot”。谢谢@seanb!我无法使用SQL Server/t-SQL,因此无法使用循环来添加和更新表。但是你的方法是有效的!我可以使用的功能非常有限,但您的步骤启发我继续使用该方法学可以做的事情
DECLARE @CustomSQL nvarchar(4000);
DECLARE @n int = 1;
DECLARE @ColName nvarchar(100);
DECLARE @ColNametxt nvarchar(100);

SELECT      @ColName = ColName,
            @ColNameTxt = ColNameTxt
    FROM    #ColNames 
    WHERE   ColNum = @n;

WHILE @ColName IS NOT NULL
    BEGIN

    SET @CustomSQL = N'ALTER TABLE #pvttable ADD ' + @ColName + N' nvarchar(100);';
    EXEC (@CustomSQL);

    SET @CustomSQL = 
        N'UPDATE #pvttable SET ' + @Colname + N' = table1.col2'
        + N' FROM #pvttable INNER JOIN table1 ON #pvttable.col1 = table1.col3'
        + N' WHERE table1.col1 = N''' + @ColNametxt + N''';';
    EXEC (@CustomSQL);

    SET @n += 1;

    SET @ColName = NULL;
    SET @ColNametxt = NULL;

    SELECT      @ColName = ColName,
                @ColNameTxt = ColNameTxt
        FROM    #ColNames 
        WHERE   ColNum = @n;

    END;

SELECT * FROM #pvttable;