按日期/小时/分钟,并加入表的SQL组记录

问题描述 投票:0回答:3

考虑下面的2个表

表A

|ParameterId|ParameterName|
|-----------|-------------|
|0          |Param_A      |
|1          |Param_B      |
|2          |Param_C      |
|3          |Param_D      |

表B

|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             |

我怎么能按日期,小时和分钟,并在表中的数据与表中加入如下得到的结果:

|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      |
sql sql-server
3个回答
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 

Online Demo

注意:如果你想在你应该做的像下面这种情况下,不包括秒和毫秒时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 

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省略日期时间的接触/倒 - 这部分是微不足道的,但恼人的处理。


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
© www.soinside.com 2019 - 2024. All rights reserved.