0

小提琴示例:http://sqlfiddle.com/#!3/419ec/ 3

2008 年的 SQL 服务器。

我想知道是否有人可以使用替换功能和取消透视功能向我解释下面的选择查询中发生了什么。我是 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函数的用法如下:

REPLACE ( string_expression , string_pattern , string_replacement )

string_expression

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

根据replace函数的定义,string_expression 是正在其中搜索子字符串的字符串(子字符串可以是完整字符串)。例如,

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

john这将在 string_expression 中搜索子字符串mynameisjohn并将其替换为空字符串,从而生成一个等于 的字符串mynameis

但在上面的例子中,我不明白是什么MightyMouse。原表中没有MightyMouse。我也不知道 unpivot 部分如何像在执行流程中那样适合查询。

例如,如果这是 python,那么代码的逻辑就会很直观。使用 SQL,您似乎可以构建丑陋的查询,并且从 sql 的角度来看,一切都很好。但从用户的角度来看,可能很难分解查询代码的不同部分中发生的事情。

4

3 回答 3

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
于 2013-04-24T22:01:28.710 回答
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 在做什么以及它为什么起作用。


至于有效的(*) 执行顺序:在 SQL Query 中,FROM子句总是首先WHERE执行,然后是子句。子句(列SELECT列表和列表达式)几乎在最后,而ORDER BY子句通常在最后(有一些特定于 MS 的例外)。

(* - 这只是“有效”/“逻辑”的执行顺序。允许 SQL 引擎按照它想要的任何实际顺序执行操作,只要它具有与此顺序相同的逻辑效果)

于 2013-04-24T22:19:05.973 回答
0

“MightMouse”是新列的名称。从本质上讲,您将所有这些小时列合并到一个列中。“for MightMouse in ...”正在调用列 MightMouse。那么,您将用空字符串替换该新列中的文字字符串“小时”。

于 2013-04-24T21:10:19.737 回答