【问题标题】:Literal transpose columns to single column rows文字转置列到单列行
【发布时间】:2016-02-03 21:30:25
【问题描述】:

TSQL 问题(MS Sql Server 2012) 我有一个表,其中包含代表服务器的行。每台服务器都有一个用于故障转移的备用服务器,因此我表中的每一行都有一个服务器 ID(键)列和一个表示指定备份服务器键的列。

我已经针对这个表编写了一个查询来查找不匹配的行,并且该查询每行返回三个键值。每列都是一个键值,表示参与不匹配的服务器。在大多数情况下,我们会看到每个不匹配的三个服务器——其中服务器 1 显示它的配对是服务器 2,而服务器 2 与另一台服务器(服务器 3)配对。

目前,我已成功找到不匹配项,如以下示例结果所示:

    12345, 23456, 34567
    23424, 89234, 43453

第一列是主服务器 ID,第二列是它的辅助服务器的当前键,第三列是辅助服务器的行显示的与其主要匹配的值。当第三列与第一列不同时,这是不匹配的,我想详细查看所有这些行。

要进行该检查,我想使用查询结果来查找在后续选择中不匹配的行的 ID,以获取代码表示的每条完整记录的详细信息,例如

    select * from foo where foo.id in (12345, 23456, 34567, ...)

但是,我不知道我想要的 ID,所以它会采用以下形式:

    select * from foo where foo.id in (subquery)

由于想在子查询中使用我的查询结果作为一个集合,子查询需要每行返回一个值而不是三个(我想查看标识的所有三行,作为我的使用案例是查找存在数据质量问题的记录)

如何轻松地将结果从列转换为行?我没有聚合要做(因此枢轴/取消枢轴似乎出来) - 但对于选择列表,我需要子查询返回不同的行,每行一个值而不是每行三个值。

我知道我可以做一个 big-old-union,重复相同的复杂自联接来找到我需要的三列,一次一列,称它们为相同的值。返回三个值的子查询已经有点贵了,所以我想尽可能避免这种情况。

看来我需要做的就是将列转换为行 - 无需进行任何计算。怎么样?

【问题讨论】:

标签: sql-server


【解决方案1】:

Tab Alleman 的提示让我得到了我需要的答案 - Cross Apply 让您能够在不聚合的情况下重新格式化结果。

为简单起见,我的详细子查询可以压缩为:

    with foobar (code1, code2, code3)
    as
    ( 
        very complicated query that returns my results goes here 
    )

    select * from details where code in (select distinct u.code from foobar t
        cross apply
        (
            select code1
            union all
            select code2
            union all
            select code3
        ) u code )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    • 1970-01-01
    • 2019-11-14
    • 2013-07-29
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    相关资源
    最近更新 更多