将多列拆分为多行
我有一个具有这种结构的表。
UserID | UserName | AnswerToQuestion1 | AnswerToQuestion2 | AnswerToQuestion3
1 | John | 1 | 0 | 1
2 | Mary | 1 | 1 | 0
我无法弄清楚我将使用什么 SQL 查询来获得这样的结果集:
UserID | UserName | QuestionName | Response
1 | John | AnswerToQuestion1 | 1
1 | John | AnswerToQuestion2 | 0
1 | John | AnswerToQuestion3 | 1
2 | Mary | AnswerToQuestion1 | 1
2 | Mary | AnswerToQuestion2 | 1
2 | Mary | AnswerToQuestion3 | 0
我试图将三列拆分为三个单独的行。这可能吗?
I have a table with this structure.
UserID | UserName | AnswerToQuestion1 | AnswerToQuestion2 | AnswerToQuestion3
1 | John | 1 | 0 | 1
2 | Mary | 1 | 1 | 0
I can't figure out what SQL query I would use to get a result set like this:
UserID | UserName | QuestionName | Response
1 | John | AnswerToQuestion1 | 1
1 | John | AnswerToQuestion2 | 0
1 | John | AnswerToQuestion3 | 1
2 | Mary | AnswerToQuestion1 | 1
2 | Mary | AnswerToQuestion2 | 1
2 | Mary | AnswerToQuestion3 | 0
I'm trying to split the three columns into three separate rows. Is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
假设 SQL Server 2005+ 您可以使用 UNPIVOT
Assuming SQL Server 2005+ you can use UNPIVOT
根据 Itzik Ben-Gan 在Inside Microsoft SQL Server 2008:T-SQL 查询中的说法,SQL Server 在逆透视表时会经历三个步骤:
第 1 步:生成副本
将创建一个虚拟表,该表对于要取消透视的每一列都有原始表中每一行的副本。
此外,列名称的字符串存储在新列(称为 QuestionName 列)中。 *注意:我将其中一列中的值修改为 NULL 以显示完整的过程。
第 2 步:提取元素
然后创建另一个表,为对应的源列中的每个值创建一个新行
到 QuestionName 列中的字符串值。该值存储在一个新列中(称为响应列)。
步骤 3:删除包含 NULL 的行
此步骤会过滤掉在“响应”列中使用空值创建的任何行。换句话说,
如果任何 AnswerToQuestion 列具有空值,则它不会表示为未透视的行。
如果您按照这些步骤操作,则可以
用于获取行副本的列名称
在匹配源列和 QuestionName 时
不使用 UNPIVOT 的结果。
下面是一个例子:
According to Itzik Ben-Gan in Inside Microsoft SQL Server 2008: T-SQL Querying, SQL Server goes through three steps when unpivoting a table:
Step 1: Generate copies
A virtual table is created that has a copy of each row in the orignal table for each column that is being unpivoted.
Also, a character string of the column name is stored in a new column (call this the QuestionName column). *Note: I modified the value in one of your columns to NULL to show the full process.
Step 2: Extract elements
Then another table is created that creates a new row for each value from the source column which corresponds
to the character string value in the QuestionName column. The value is stored in a new column (call this the Response column).
Step 3: Remove rows with NULLS
This step filters out any rows that were created with null values in the Response column. In other words,
if any of the AnswerToQuestion columns had a null value, it would not be represented as an unpivoted row.
If you follow those steps, you can
column name to get row copies
on the matching the source column and QuestionName
results without using UNPIVOT.
An example below:
这与 UNPIVOT 的性能同样好(有时更好),并且也适用于 SQL 2000。
我利用问题的相似性来创建 QuestionName 列,但这当然适用于不同的问题名称。
请注意,如果您的问题列表很长或问题名称很长,您可以尝试在 X 表中使用 2 列,一列用于问题编号,一列用于问题名称。或者,如果您已经有一个包含问题列表的表格,则可以交叉连接到该表格。如果某些问题为 NULL,那么最简单的方法是将上述查询放入 CTE 或派生表中,然后添加
WHERE Response IS NOT NULL
。This performs equally well to UNPIVOT (sometimes better) and works in SQL 2000 as well.
I took advantage of the questions' similarity to create the QuestionName column, but of course this will work with varying question names.
Note that if your list of questions is long or the question names are long, you might experiment with 2 columns in the X table, one for the question number and one for the question name. Or if you already have a table with the list of questions, then CROSS JOIN to that. If some questions are NULL then easiest is to put the above query in a CTE or derived table and then add
WHERE Response IS NOT NULL
.