给出以下2个表
TableA
|ParameterId|ParameterName|
|-----------|-------------|
|0 |Param_A |
|1 |Param_B |
|2 |Param_C |
|3 |Param_D |
TableB
|LogDateTime |ParameterId|ParameterValue|
|-------------------|-----------|--------------|
|2019-01-29 00:00:12|0 |4 |
|2019-01-29 00:00:14|1 |2 |
|2019-01-29 00:00:17|2 |0 |
|2019-01-29 00:00:21|3 |1 |
|2019-01-30 00:01:13|0 |7 |
|2019-01-30 00:01:17|1 |3 |
|2019-01-30 00:01:22|2 |5 |
|2019-01-30 00:01:23|3 |9 |
|2019-01-31 00:02:20|0 |3 |
|2019-01-31 00:02:33|1 |0 |
|2019-01-31 00:02:41|2 |1 |
|2019-01-31 00:02:41|3 |6 |
如何按日期,小时和分钟对TableB中的数据进行分组,并与TableA结合以得到如下结果:
|LogDateTime |Param_A|Param_B|Param_C|Param_D|
|----------------|-------|-------|-------|-------|
|2019-01-29 00:00|4 |2 |0 |1 |
|2019-01-30 00:01|7 |3 |5 |9 |
|2019-01-31 00:02|3 |0 |1 |6 |
答案 0 :(得分:0)
使用CTE和数据透视表,如下所示:
with _prep as (
select
LogDateTime=DateHourMinute(LogDateTime),
ParameterName,
ParameterValue
from TableB b
inner join TableA a on b.parameterID = a.parameterID
),
select LogDateTime, Param_A,Param_B,Param_C,Param_D
from (
select LogDateTime, ParameterValue, ParameterName
from _prep
) x
pivot (
max(ParameterValue)
for parameterName in (Param_A,Param_B,Param_C,Param_D)
) p
请注意,我通过使用模拟DateHourMinute省略了日期时间的联系/舍入-这部分虽然微不足道,但令人讨厌。
答案 1 :(得分:0)
您可以使用PIVOT
来获得所需的输出,例如以下查询。
;WITH cte1
AS (SELECT B.*,P.parametername
FROM @tableB B
INNER JOIN @tableA P
ON B.parameterid = P.parameterid)
SELECT *
FROM (SELECT
Cast(logdatetime AS SMALLDATETIME) AS logdatetime,
parametervalue,
parametername
FROM cte1) AS SourceTable
PIVOT ( SUM(parametervalue)
FOR parametername IN ([Param_A],[Param_B], [Param_C],[Param_D] )) T
注意::如果要在排除秒和毫秒的情况下ROUND
分钟,则应遵循以下步骤。
CAST(logdatetime AS smalldatetime)
如果您只想截断秒和毫秒,可以按照以下步骤进行更改。
CAST(DateAdd(minute, DateDiff(minute, 0, logdatetime), 0) AS smalldatetime)
如果您的TableA
的值不是固定的(将来可能会有所变化),那么在这种情况下,您需要使用动态的PIVOT
。
如果参数是固定的,另一个更简单的解决方案类似于使用CASE WHEN
进行以下查询。
;WITH cte
AS (SELECT Cast(logdatetime AS SMALLDATETIME) AS DT,
CASE WHEN parameterid = 0 THEN parametervalue END AS 'Param_A',
CASE WHEN parameterid = 1 THEN parametervalue END AS 'Param_B',
CASE WHEN parameterid = 2 THEN parametervalue END AS 'Param_C',
CASE WHEN parameterid = 3 THEN parametervalue END AS 'Param_D'
FROM @TableB)
SELECT dt AS LogDateTime,
Isnull(Sum(param_a), 0) AS Param_A,
Isnull(Sum(param_b), 0) AS Param_B,
Isnull(Sum(param_c), 0) AS Param_C,
Isnull(Sum(param_d), 0) AS Param_D
FROM cte
GROUP BY dt
答案 2 :(得分:0)
一种可能的方法是旋转数据。如果参数计数是动态的,则可能需要生成动态语句。
输入:
-- Tables
CREATE TABLE #TableA (
ParameterId int,
ParameterName varchar(10)
)
INSERT INTO #TableA
(ParameterId, ParameterName)
VALUES
(0, 'Param_A'),
(1, 'Param_B'),
(2, 'Param_C'),
(3, 'Param_D')
CREATE TABLE #TableB (
LogDateTime datetime,
ParameterId int,
ParameterValue int
)
INSERT INTO #TableB
(LogDateTime, ParameterId, ParameterValue)
VALUES
('2019-01-29T00:00:12', 0, 4),
('2019-01-29T00:00:14', 1, 2),
('2019-01-29T00:00:17', 2, 0),
('2019-01-29T00:00:21', 3, 1),
('2019-01-30T00:01:13', 0, 7),
('2019-01-30T00:01:17', 1, 3),
('2019-01-30T00:01:22', 2, 5),
('2019-01-30T00:01:23', 3, 9),
('2019-01-31T00:02:20', 0, 3),
('2019-01-31T00:02:33', 1, 0),
('2019-01-31T00:02:41', 2, 1),
('2019-01-31T00:02:41', 3, 6)
声明:
-- Statement
SELECT
-- Non-pivoted and pivoted columns
[LogDateTime],
[Param_A],
[Param_B],
[Param_C],
[Param_D]
FROM (
-- SELECT statement that produces the data
SELECT
b.ParameterValue,
LEFT(CONVERT(varchar(19), b.LogDateTime, 120), 16) AS LogDateTime,
a.ParameterName
FROM #TableB b
LEFT JOIN #TableA a ON (b.ParameterID = a.ParameterID)
) d
PIVOT (
-- Rotate data with PIVOT
SUM ([ParameterValue])
FOR [ParameterName] IN ([Param_A], [Param_B], [Param_C], [Param_D])
) p
输出:
LogDateTime Param_A Param_B Param_C Param_D
2019-01-29 00:00 4 2 0 1
2019-01-30 00:01 7 3 5 9
2019-01-31 00:02 3 0 1 6