UNPIVOT 假期时间
UNPIVOT Holiday Hours
我有一个 table,可以跟踪商店假期营业时间:
LOCATION_ID DATE1 TIMES1 DATE2 TIMES2
123456 2020-12-12 10:00AM-09:00PM 2020-12-19 10:00AM-09:00PM
这是一个高度简化的 table。大约有 30 列按日期水平排列的商店营业时间 - 它继续(DATE3、TIMES3、DATE4、TIMES4 等)。
我需要垂直反转值,确保日期和时间值在同一条记录上。
(注意:一旦我想出正确构造 UNPIVOT
表达式,我将自己使用 Dynamic SQL 来转换列名称)
期望的结果:
LOCATION_ID DATE TIME
123456 2020-12-12 10:00AM-09:00PM
123456 2020-12-19 10:00AM-09:00PM
我尝试使用 UNPIVOT
,但我卡住了。有什么想法吗?
示例数据:
CREATE TABLE #HOURS (LOCATION_ID int, DATE1 varchar(255), TIMES1 varchar(255), DATE2
varchar(255), TIMES2 varchar(255));
INSERT INTO #HOURS VALUES ('123456', '2020-12-12', '10:00AM-09:00PM','2020-12-19','10:00AM-09:00PM' )
我试过的代码:
SELECT *
FROM (SELECT location_id,
[date1],
[times1],
[date2]
FROM #hours) AS cp
UNPIVOT ( pivotvalues
FOR pivvalues IN ([Date1],
[date2],
[times1]) ) AS up1
不要使用 unpivot
。使用 apply
:
select h.location_id, v.date, v.time
from #hours h cross apply
(values (h.date1, h.times1), (h.date2, h.times2)
) v(date, time);
unpivot
是只做一件事的非标准语法。 APPLY
是 横向连接 的 SQL 服务器实现。这是一个非常强大的 join
类型——用它来逆透视是开始学习语法的好方法。
戈登 100% 正确 (+1)。
但是,如果您正在寻找无需使用动态 SQL 的动态方法,请考虑以下内容。
例子
Select Location_ID
,Date = max(case when [Item] like 'DATE%' then Value end)
,Time = max(case when [Item] like 'TIME%' then Value end)
From (
select A.Location_ID
,Grp = replace(replace([Item],'DATE',''),'TIMES','')
,B.*
from #hours A
Cross Apply [dbo].[tvf-XML-Unpivot-Row]( (Select A.* for XML RAW) ) B
Where [Item] not in ('LOCATION_ID')
) A
Group By Location_ID,Grp
Returns
Location_ID Date Time
123456 2020-12-12 10:00AM-09:00PM
123456 2020-12-19 10:00AM-09:00PM
Table-值函数如果感兴趣
CREATE FUNCTION [dbo].[tvf-XML-UnPivot-Row](@XML xml)
Returns Table
As
Return (
Select Item = xAttr.value('local-name(.)', 'varchar(100)')
,Value = xAttr.value('.','varchar(max)')
From @XML.nodes('//@*') xNode(xAttr)
)
我有一个 table,可以跟踪商店假期营业时间:
LOCATION_ID DATE1 TIMES1 DATE2 TIMES2
123456 2020-12-12 10:00AM-09:00PM 2020-12-19 10:00AM-09:00PM
这是一个高度简化的 table。大约有 30 列按日期水平排列的商店营业时间 - 它继续(DATE3、TIMES3、DATE4、TIMES4 等)。
我需要垂直反转值,确保日期和时间值在同一条记录上。
(注意:一旦我想出正确构造 UNPIVOT
表达式,我将自己使用 Dynamic SQL 来转换列名称)
期望的结果:
LOCATION_ID DATE TIME
123456 2020-12-12 10:00AM-09:00PM
123456 2020-12-19 10:00AM-09:00PM
我尝试使用 UNPIVOT
,但我卡住了。有什么想法吗?
示例数据:
CREATE TABLE #HOURS (LOCATION_ID int, DATE1 varchar(255), TIMES1 varchar(255), DATE2
varchar(255), TIMES2 varchar(255));
INSERT INTO #HOURS VALUES ('123456', '2020-12-12', '10:00AM-09:00PM','2020-12-19','10:00AM-09:00PM' )
我试过的代码:
SELECT *
FROM (SELECT location_id,
[date1],
[times1],
[date2]
FROM #hours) AS cp
UNPIVOT ( pivotvalues
FOR pivvalues IN ([Date1],
[date2],
[times1]) ) AS up1
不要使用 unpivot
。使用 apply
:
select h.location_id, v.date, v.time
from #hours h cross apply
(values (h.date1, h.times1), (h.date2, h.times2)
) v(date, time);
unpivot
是只做一件事的非标准语法。 APPLY
是 横向连接 的 SQL 服务器实现。这是一个非常强大的 join
类型——用它来逆透视是开始学习语法的好方法。
戈登 100% 正确 (+1)。
但是,如果您正在寻找无需使用动态 SQL 的动态方法,请考虑以下内容。
例子
Select Location_ID
,Date = max(case when [Item] like 'DATE%' then Value end)
,Time = max(case when [Item] like 'TIME%' then Value end)
From (
select A.Location_ID
,Grp = replace(replace([Item],'DATE',''),'TIMES','')
,B.*
from #hours A
Cross Apply [dbo].[tvf-XML-Unpivot-Row]( (Select A.* for XML RAW) ) B
Where [Item] not in ('LOCATION_ID')
) A
Group By Location_ID,Grp
Returns
Location_ID Date Time
123456 2020-12-12 10:00AM-09:00PM
123456 2020-12-19 10:00AM-09:00PM
Table-值函数如果感兴趣
CREATE FUNCTION [dbo].[tvf-XML-UnPivot-Row](@XML xml)
Returns Table
As
Return (
Select Item = xAttr.value('local-name(.)', 'varchar(100)')
,Value = xAttr.value('.','varchar(max)')
From @XML.nodes('//@*') xNode(xAttr)
)