SQL pivot表1转换为表2,而不使用动态SQL pivot或硬代码查询
我已经看到了许多关于使用SQL数据透视表、使用动态SQL数据透视或使用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
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;