Tsql 查找列对中的值差

Tsql 查找列对中的值差,tsql,sql-server-2008-r2,Tsql,Sql Server 2008 R2,我正在使用SQL server 2008R2,我有一个返回以下内容的视图: +----+-------+-------+-------+-------+-------+-------+ | ID | col1A | col1B | col2A | col2B | col3A | col3B | +----+-------+-------+-------+-------+-------+-------+ | 1 | 1 | 1 | 3 | 5 | 4 |

我正在使用SQL server 2008R2,我有一个返回以下内容的视图:

+----+-------+-------+-------+-------+-------+-------+
| ID | col1A | col1B | col2A | col2B | col3A | col3B |
+----+-------+-------+-------+-------+-------+-------+
|  1 |     1 |     1 |     3 |     5 |     4 |     4 |
|  2 |     1 |     1 |     5 |     5 |     5 |     4 |
|  3 |     3 |     4 |     5 |     5 |     4 |     4 |
|  4 |     1 |     2 |     5 |     5 |     4 |     3 |
|  5 |     1 |     1 |     2 |     2 |     3 |     3 |
+----+-------+-------+-------+-------+-------+-------+
如您所见,此视图包含列对(col1A和col1B),(col2A和col2B),(col3A和col3B)

我需要查询这个视图并找到列对包含不同值的行。 因此,我希望返回:

+----+------------+---+-----+
| ID | ColumnType | A |  B  |
+----+------------+---+-----+
|  1 | Col2       | 3 | 5   |
|  2 | Col3       | 5 | 4   |
|  3 | Col1       | 3 | 4   |
|  4 | Col1       | 1 | 2   |
|  4 | Col3       | 4 | 3   |
+----+------------+---+-----+

我想我需要使用UNPIVOT,但不知道如何使用–感谢您的建议?

因为您使用的是SQL Server 2008+,所以可以使用
交叉应用
来取消对列的pivot,然后您可以轻松比较
A
B
中的值以返回不匹配的行:

select t.ID,
    c.ColumnType,
    c.A,
    c.B
from [dbo].[yourview] t
cross apply
(
    values 
        ('Col1', Col1A, Col1B),
        ('Col2', Col2A, Col2B),
        ('Col3', Col3A, Col3B)
) c (ColumnType, A, B)
where c.A <> c.B;

事实上,我不得不重新考虑这个问题。如果所有列类型都是相同或兼容的数据类型,则此操作有效。但是失败如果例如col1A和Col1B是INT类型,而Col2A和col2B是Date类型,那么它将失败并出现错误:Msg 206,级别16,状态2,第1行操作数类型冲突:INT与Date不兼容我不确定为什么会出现这种情况,因为我认为值的比较将在相同的列类型上(Col1A Col1B、Col2A Col2B、Col3A Col3B)???@user3801452如果数据类型不同,则需要将它们转换为相同的数据类型。您可以在
values
子句中执行此转换/转换。当您将多列转换为单列时,则存储的所有数据类型都必须相同。如果您有int和datetime,则可能我必须考虑使用
varchar
。谢谢你,我有int、varchar、dates和decimals。我将使用convert to varchar进行测试。
select t.ID,
    c.ColumnType,
    c.A,
    c.B
from [dbo].[yourview] t
cross apply
(
    values 
        ('Col1', cast(Col1A as varchar(50)), Col1B),
        ('Col2', cast(Col2A as varchar(50)), Col2B),
        ('Col3', cast(Col3A as varchar(50)), Col3B)
) c (ColumnType, A, B)
where c.A <> c.B