这里的小提琴示例:http://sqlfiddle.com/#!3/419ec/3
SQL server 2008。
我想知道是否有人可以通过替换功能和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是搜索子字符串的字符串(子字符串可以是完整字符串)。例如,
replace('mynameisjohn', 'john', '')
这将在string_expression john
中搜索子字符串mynameisjohn
并将其替换为空字符串,从而生成一个等于mynameis
的字符串。
但在上面的例子中,我不明白MightyMouse
是什么。原始表中没有MightyMouse
。我也不知道unpivot部分如何适合查询,如在执行流程中。
如果这是python,例如,代码的逻辑流是直观的。使用SQL,似乎你可以构建丑陋的查询,从sql的角度来看,一切正常。但是从用户的角度来看,很难分解查询代码的不同部分中发生的事情。
答案 0 :(得分:1)
Unpivot为您的案例中指定的每个列使用嵌套的左外连接
(hour1, hour2, hour3, hour4)
这些列名也是结果的一部分,在你的案例中称为MightMouse
select replace('hour1','hour','')
select replace('hour2','hour','')
select replace('hour3','hour','')
换句话说,可以像这样编写相同的查询
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
答案 1 :(得分:1)
UNPIVOT
是一个表运算符,它在它之前的表上运行:
tableName UNPIVOT (<unpivot-expression>)
您的UNPIVOT
添加两个额外列(不是暗示的一个),首先是observationvalue
列,其中包含(hour1, hour2, hour3, hour4)
列中的值从水平旋转到垂直。
其次,它会添加MightMouse
列,即(hour1, hour2, hour3, hour4)
列的名称,相应的当前observationvalue
被拉出。
所以这一行:
hour1, hour2, hour3, hour4
129, 343, 54, 89
成为这些行:
observationvalue MightMouse
129 hour1
343 hour2
54 hour3
89 hour4
(当然还有其他相应的列值)
希望这也能说明REPLACE正在做什么以及它为什么会起作用。
对于有效(*)执行顺序:FROM
子句总是在SQL查询中执行 first ,然后是{{1} }子句。 WHERE
子句(列列表和列表达式)几乎是最后一个,SELECT
子句通常是最后一个(有一些MS特定的例外)。
(* - 这只是执行的“有效”/“逻辑”顺序。允许SQL引擎按照它想要的任何实际顺序执行操作,只要它具有与此顺序相同的逻辑效果)
答案 2 :(得分:0)
“MightMouse”是新列的名称。从本质上讲,您将把所有这些小时列并将它们分成一列。 “for MightMouse in ...”正在调用MightMouse专栏。那么,您将使用空字符串替换新列中的文字字符串“hour”。