2013-04-24 28 views
0

小提琴這裏舉例:http://sqlfiddle.com/#!3/419ec/3SQL: - 更換和UNPIVOT功能在查詢

SQL Server 2008的

我想知道是否有人可以請給我解釋一下什麼是下面的select查詢怎麼回事替換功能和unpivot功能。我是一個新手到SQL,我不明白這種類型的查詢的邏輯(解規範表)。

CREATE TABLE TableB 
    ([date] datetime, [Id] int, [name] varchar(3), [blah1] varchar(4), [hour1] int, [hour2] int, [hour3] int, [hour4] int) 
; 

INSERT INTO TableB 
    ([date], [Id], [name], [blah1], [hour1], [hour2], [hour3], [hour4]) 
VALUES 
    ('2013-04-01 00:00:00', 1, 'Jim', 'test', 129, 343, 54, 89), 
    ('2013-04-01 00:00:00', 2, 'Bob', 'rewe', 45, 6, 45, 2), 
    ('2013-04-02 00:00:00', 3, 'Joe', 'fdf', 7, 8, 4, 3) 

選擇查詢:

select date, 
    id, 
    name, 
    replace(MightMouse, 'hour', '') hour, 
    observationvalue 
from tableB 
unpivot 
(
    observationvalue 
    for MightMouse in (hour1, hour2, hour3, hour4) 
) unpiv 

我想替換函數的用法如下:

REPLACE (string_expression , string_pattern , string_replacement) 

string_expression 

http://msdn.microsoft.com/en-us/library/ms186862.aspx

由於每replace函數的定義, string_expression是其中一個子串i的字符串s被搜索(子字符串可以是完整的字符串)。例如,

replace('mynameisjohn', 'john', '') 

這將在string_expression mynameisjohn搜索子串john,並用空字符串替換,導致等於mynameis的字符串。

但在上面的例子中,我不明白MightyMouse是什麼。原表中沒有MightyMouse。我也不知道unpivot部分如何在執行流程中適合查詢。

如果這是python例如有一個直觀的代碼邏輯流。使用SQL,看起來你可以構建醜陋的查詢,並且從sql的角度來看,事情工作得很好。但是從用戶的角度來看,很難分解查詢代碼不同部分發生的事情。

回答

1

UNPIVOT是一個表運算符,它的操作在桌子上前述它:

tableName UNPIVOT (<unpivot-expression>) 

UNPIVOT增加額外的列(而不是一個因爲已經暗示),首先observationvalue列,其中包含從列中的值(hour1, hour2, hour3, hour4)從水平轉到垂直。

其次它增加了MightMouse列這是名稱與對應當前observationvalue從拉(hour1, hour2, hour3, hour4)

因此該行:(也與其他相應的列值,當然)

observationvalue MightMouse 
129    hour1 
343    hour2 
54    hour3 
89    hour4 

希望,這也使得清楚的:

hour1, hour2, hour3, hour4 
129, 343, 54, 89 

成爲這些行REPLACE正在做,爲什麼它會工作。


至於執行的有效(*)的順序:在SQL查詢的FROM子句總是執行第一,則WHERE子句。 SELECT子句(列列表和列表達式)幾乎是最後一個,並且ORDER BY子句通常是最後一個(有一些MS特定的例外)。 (* - 這只是執行的「有效」/「邏輯」順序,SQL引擎可以按照任何實際順序執行任何事情,只要它具有與此順序相同的邏輯效果)

+0

謝謝RBarry的詳細解釋。所以我想'MightMouse'列名根據替換(MightMouse,'hour','')小時聲明重新命名爲'hour' - 是否正確? – codingknob 2013-04-24 23:02:08

+0

那麼'MightMouse'有一個列名「MightMouse」。被替換的是MightMouse列的*內容*,它們是從源列名稱('hour1,hour2,...')構建的。 – RBarryYoung 2013-04-24 23:29:41

0

「MightMouse」是新列的名稱。基本上,你正在把所有這些小時的專欄和他們衝進一個專欄。 「for MightMouse in ...」正在呼喚MightMouse專欄。那麼,您將用空字符串替換新列中的字符串「小時」。

+0

戴夫感謝您的評論。所以我創建了一個新的列「MightMouse」,它不會出現在最終的查詢輸出中,但它在那裏用於處理查詢?然後,它將所有小時的列清理成名爲'hour'的小時。我仍然不明白查詢的流程。什麼部分首先被執行? unpivot是否先執行? – codingknob 2013-04-24 22:02:03

1

逆透視使用嵌套左外連接針對你的情況中指定的每個列

(hour1, hour2, hour3, hour4) 

這些列名也是其在你的情況

select replace('hour1','hour','') 
select replace('hour2','hour','') 
select replace('hour3','hour','') 

在其他稱爲MightMouse結果的一部分單詞相同的查詢可以這樣寫:

select a.date,a.id, 
    a.name,replace('hour1', 'hour', '') as hour ,a.hour1 as observationvalue 
from TableB a 
left outer join TableB b 
on a.hour1=b.hour1 
where a.hour1 is not null 
union 

select a.date,a.id, 
    a.name,replace('hour2', 'hour', '') as hour ,a.hour2 as observationvalue 
from TableB a 
left outer join TableB b 
on a.hour2=b.hour2 
where a.hour2 is not null 
union 
select a.date,a.id, 
    a.name,replace('hou3', 'hour', '') as hour ,a.hour3 as observationvalue 
from TableB a 
left outer join TableB b 
on a.hour3=b.hour3 
where a.hour3 is not null 
union 
select a.date,a.id, 
    a.name,replace('hour4', 'hour', '') as hour ,a.hour4 as observationvalue 
from TableB a 
left outer join TableB b 
on a.hour4=b.hour4 
where a.hour4 is not null 
+0

感謝您的評論。我很感激。但是在a.hour1 = b.hour1上的「left outer join TableB b」,其中a.hour1不是null部分是必要的嗎?我在每個小時執行相同的代碼而沒有這個部分,並且它產生相同的結果。 – codingknob 2013-04-24 22:56:23