sql: - 在查询中替换和取消忽略函数

时间:2013-04-24 20:57:45

标签: sql sql-server replace unpivot

这里的小提琴示例: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的角度来看,一切正常。但是从用户的角度来看,很难分解查询代码的不同部分中发生的事情。

3 个答案:

答案 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”。