2016-02-03 87 views
0

TSQL問題(MS Sql Server 2012) 我有一個包含表示服務器的行的表。每臺服務器都有一個用於故障切換的備份服務器,因此我表格中的每一行都有一個用於服務器ID(密鑰)的列和一個表示指定備份服務器密鑰的列。將列轉置爲單列行

我寫了一個針對這個表的查詢,發現不匹配的行,並且該查詢每行返回三個鍵值。每列是表示參與不匹配的服務器的關鍵值。在大多數情況下,我們會看到三個服務器的每個不匹配 - 服務器1顯示它的對是服務器2,而服務器2與另一個服務器(服務器3)有配對。

目前我成功發現錯配如下面的示例結果表明:

12345, 23456, 34567 
    23424, 89234, 43453 

第一列是在主服務器ID,第2欄是當前鍵爲它的次級,並且第三列是輔助行顯示其主要匹配的值。當第三列與第一列不同時,這是不匹配的,我想詳細查看所有這些行。

爲了做到這一點檢查,我想使用發現不匹配在隨後的選擇,以獲得詳細信息對於每個完整的記錄,該代碼表示​​行的ID的查詢結果,如

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

但是,我不知道該ID的我想要的,所以它會採取以下形式:

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

由於想使用我查詢的結果爲一組在一個子查詢中,子查詢需要每行返回一個值而不是三個(我想查看所有三行標識符因爲我的用例是查找具有數據質量問題的記錄)

如何將結果從列轉換爲行很容易?我沒有聚合做(因此樞軸/ unpivot似乎出) - 但對於選擇列表我需要子查詢返回不同的行,每行一個值,而不是每行三個值。

我知道我可以做一個很古老的聯盟,重複同樣的複雜自聯接來查找我需要的三列,每次一列,並將它們稱爲相同的值。返回三個值的子查詢已經有點貴了,所以我想盡可能避免這種情況。

看起來我需要做的就是將列轉置爲行 - 不需要計算。怎麼樣?

+0

做這些的幫助? https://www.google.com/search?sourceid=navclient&aq=&oq=stack+overflow+sql+server+unpivot+without+aggregation&ie=UTF-8&rlz=1T4GGNI_enUS551US551&q=stack+overflow+sql+server+unpivot+without+聚合&gs_l =馬力.... 0.0.0.7612 ........... 0.rpE0P9FNpf4 –

回答

0

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)