我的数据结构如下:
LocationId, GroupId, DayOfWeek, Count, DatetimeValue15Min
2 9 4 5 2014-01-02 08:15:00.000
2 9 4 5 2014-01-02 09:15:00.000
我想计算每一天的模式,上面的数据已经包含了解模式的计数。我用一个数据库写了一个查询。
SELECT
pvt.LocationId, pvt.GroupId, [1], [2], [3], [4],[5]
FROM
@TempResult
PIVOT
(min ([DatetimeValue15Min])
FOR DayOfWeek IN ( [1], [2], [3], [4],[5])) AS pvt
在这种情况下,我有两种模式,但我想同时显示它们。在这种情况下,我的查询返回的是具有最小值的模式。我知道我可以用最大值进行第二次查询,但如果我有两种以上的模式呢?
输出应该是:
LocationId GroupId 1 2 3 4 5
2 9 08:15, 09:15
我正在使用SQL Server 2005。
答案 0 :(得分:1)
你快到了。您只需要构建以逗号分隔的列表。一个小的xml类型滥用对此非常有用。
;WITH
t1 AS ( --Add a grouping id for quick reference
SELECT
[LocationId],[GroupId],[DayOfWeek],[DatetimeValue15Min],
DENSE_RANK() OVER(ORDER BY [LocationId],[GroupId],[DayOfWeek]) [i]
FROM @TempResult
),
t2 AS ( --Build a comma-separated list of all [DatetimeValue15Min] with same grouping id
SELECT [LocationId],[GroupId],[DayOfWeek],
CAST(REPLACE((SELECT CONVERT(time, [DatetimeValue15Min]) AS a FROM t1 WHERE [i] = t.[i] FOR xml PATH('')),'</a><a>',',') AS xml).value('a[1]','varchar(max)') [dtv_list]
FROM t1 t
)
SELECT pvt.LocationId, pvt.GroupId, [1], [2], [3], [4],[5]
FROM t2
PIVOT
(
min ([dtv_list])
FOR DayOfWeek IN ( [1], [2], [3], [4],[5])
) AS pvt
xml技巧的作用如下:
SELECT [DatetimeValue15Min] FOR XML
- &gt; <a>08:15</a><a>09:15</a>
'</a><a>'
替换为','
- &gt; <a>08:15,09:15</a>
'08:15,09:15'
答案 1 :(得分:0)
SELECT LocationId, GroupId
, STUFF (
MAX (CASE WHEN DayOfWeek = 1 AND num = 1 THEN Value ELSE '' END)
+ MAX (CASE WHEN DayOfWeek = 1 AND num = 2 THEN Value ELSE '' END), 1, 2, '') AS [1]
, STUFF (
MAX (CASE WHEN DayOfWeek = 2 AND num = 1 THEN Value ELSE '' END)
+ MAX (CASE WHEN DayOfWeek = 2 AND num = 2 THEN Value ELSE '' END), 1, 2, '') AS [2]
, STUFF (
MAX (CASE WHEN DayOfWeek = 3 AND num = 1 THEN Value ELSE '' END)
+ MAX (CASE WHEN DayOfWeek = 3 AND num = 2 THEN Value ELSE '' END), 1, 2, '') AS [3]
, STUFF (
MAX (CASE WHEN DayOfWeek = 4 AND num = 1 THEN Value ELSE '' END)
+ MAX (CASE WHEN DayOfWeek = 4 AND num = 2 THEN Value ELSE '' END), 1, 2, '') AS [4]
, STUFF (
MAX (CASE WHEN DayOfWeek = 5 AND num = 1 THEN Value ELSE '' END)
+ MAX (CASE WHEN DayOfWeek = 5 AND num = 2 THEN Value ELSE '' END), 1, 2, '') AS [5]
FROM (
SELECT LocationId, GroupId, DayOfWeek, ', ' + CONVERT (VARCHAR(5), DatetimeValue15Min, 8) AS Value
, ROW_NUMBER() OVER(PARTITION BY LocationId, GroupId, DayOfWeek ORDER BY DatetimeValue15Min) AS num
FROM @TempResult
) T
GROUP BY LocationId, GroupId
UPD。每天无限数量值的解决方案。
WITH cte AS (
SELECT LocationId, GroupId, DayOfWeek, CONVERT (VARCHAR(5), DatetimeValue15Min, 8) AS Value
, ROW_NUMBER() OVER(PARTITION BY LocationId, GroupId, DayOfWeek ORDER BY DatetimeValue15Min) AS num
FROM @TempResult
)
SELECT LocationId, GroupId
, MIN (CASE DayOfWeek WHEN 1 THEN Value END) AS [1]
, MIN (CASE DayOfWeek WHEN 2 THEN Value END) AS [2]
, MIN (CASE DayOfWeek WHEN 3 THEN Value END) AS [3]
, MIN (CASE DayOfWeek WHEN 4 THEN Value END) AS [4]
, MIN (CASE DayOfWeek WHEN 5 THEN Value END) AS [5]
FROM (
SELECT DISTINCT c1.LocationId, c1.GroupId, c1.DayOfWeek
, STUFF ( (
SELECT ', ' + c2.Value
FROM cte c2
WHERE c1.LocationId = c2.LocationId AND c1.GroupId = c2.GroupId AND c1.DayOfWeek = c2.DayOfWeek
FOR XML PATH ('')
), 1, 2, '') AS Value
FROM cte c1
) t
GROUP BY LocationId, GroupId