查询将行转换为 SQL 中的列

query to convert rows to columns in SQL

这是我的查询:

with Q1 as
 (
     select *, 
         LAG(ignition) over (ORDER BY [timestamp]) as PrevStatus, 
         LEAD(ignition) over (order by [timestamp]) as NextStatus 
     FROM vehiclehistorytable
                            WHERE plateno='Crematory' and timestamp between '2021-09-02 00:00:10.00' and '2021-09-02 23:59:59.00'
),
 Q2 as
 (
     select *,
         ROW_NUMBER() over (order by timestamp) as rn,
         LAG([volume1]) OVER (ORDER BY [timestamp]) AS VolumeIgOff                    
        
            
     from  Q1
     where PrevStatus is null or NextStatus is null or not (ignition = PrevStatus and ignition = NextStatus)
 ),
 Q3 as
 (
     select a.timestamp, a.ignition, a.volume1
     from Q2 as a
     inner join Q2 as b on b.rn = a.rn + 1
     where a.rn % 2  0
 )
 select  
 timestamp AS IgnitionOn,
 ignition,
[volume1] AS FuelLevelON                        
 from Q3
 order by timestamp




这是我目前的结果:

IgnitionOn                 ignition    FuelLevelON
2021-09-02 00:00:10.00      1             251.35
2021-09-02 00:39:09.00      0             251.35
2021-09-02 00:48:34.00      1             251.35
2021-09-02 03:24:31.00      0             208.1178
2021-09-02 03:37:22.00      1             208.1178
2021-09-02 04:59:37.00      0             181.4747
2021-09-02 05:17:14.00      1             181.4747
2021-09-02 06:20:27.00      0             159.8586
2021-09-02 06:22:29.00      1             159.8586
2021-09-02 07:30:41.00      0             140.2533
2021-09-02 11:29:38.00      1             141.2587
2021-09-02 12:41:52.00      0             117.6318
2021-09-02 12:43:22.00      1             117.6318
2021-09-02 14:07:43.00      0             254.3662
2021-09-02 14:23:49.00      1             254.3662
2021-09-02 15:31:14.00      0             238.2798
2021-09-02 15:41:02.00      1             238.2798
2021-09-02 16:46:55.00      0             218.6745
2021-09-02 16:48:25.00      1             218.6745
2021-09-02 17:55:06.00      0             196.5557
2021-09-02 18:09:03.00      1             196.5557
2021-09-02 19:09:37.00      0             174.9396
2021-09-02 19:30:26.00      1             174.9396
2021-09-02 20:56:53.00      0             152.8208
2021-09-02 21:01:40.00      1             152.8208
2021-09-02 22:08:59.00      0             135.729
                            

这是我的预期结果:

IgnitionOn              IgnitionOff    
2021-09-02 00:00:10.00   2021-09-02 00:39:09.00
2021-09-02 00:48:34.00   2021-09-02 03:24:31.00
2021-09-02 03:37:22.00   2021-09-02 04:59:37.00
2021-09-02 05:17:14.00   2021-09-02 06:20:27.00
2021-09-02 06:22:29.00   2021-09-02 07:30:41.00
2021-09-02 11:29:38.00   2021-09-02 12:41:52.00
2021-09-02 12:43:22.00   2021-09-02 14:07:43.00 
2021-09-02 14:23:49.00   2021-09-02 15:31:14.00
2021-09-02 15:41:02.00   2021-09-02 16:46:55.00
2021-09-02 16:48:25.00   2021-09-02 17:55:06.00
2021-09-02 18:09:03.00   2021-09-02 19:09:37.00
2021-09-02 19:30:26.00   2021-09-02 20:56:53.00
2021-09-02 21:01:40.00   2021-09-02 22:08:59.00

这是我的源数据车辆历史表:

timestamp               ignition       volume1   
2021-09-02 22:10:11.00      0          135.729  
2021-09-02 22:09:11.00      0          135.729  
2021-09-02 22:08:59.00      0          135.729  
2021-09-02 21:01:40.00      1          152.8208
2021-09-02 21:01:23.00      0          152.8208
2021-09-02 21:01:12.00      0          152.8208
2021-09-02 21:00:13.00      0          152.8208
2021-09-02 20:59:11.00      0          153.3235
2021-09-02 20:58:15.00      0          153.3235
2021-09-02 20:57:11.00      0          152.8208
2021-09-02 20:56:53.00      0          152.8208
2021-09-02 19:36:13.00      1          174.9396
2021-09-02 19:35:15.00      1          174.9396
2021-09-02 19:34:11.00      1          174.9396
2021-09-02 19:33:10.00      1          174.9396
2021-09-02 19:32:17.00      1          174.9396
2021-09-02 19:31:24.00      1          174.9396
2021-09-02 19:30:42.00      1          174.9396
2021-09-02 19:30:26.00      1          174.9396
2021-09-02 19:16:15.00      0          174.9396
2021-09-02 19:14:12.00      0          174.9396
2021-09-02 19:10:11.00      0          174.9396
2021-09-02 19:09:37.00      0          174.9396
2021-09-02 19:09:13.00      1          174.9396
2021-09-02 18:09:03.00      1          196.5557
2021-09-02 18:01:15.00      0          196.5557
2021-09-02 17:59:11.00      0          196.5557
2021-09-02 17:58:11.00      0          196.5557
2021-09-02 17:57:17.00      0          196.5557
2021-09-02 17:56:12.00      0          196.5557
2021-09-02 17:55:18.00      0          196.5557
2021-09-02 17:55:06.00      0          196.5557
2021-09-02 16:48:25.00      1          218.6745
2021-09-02 16:47:11.00      0          218.6745
2021-09-02 16:46:55.00      0          218.6745
2021-09-02 16:46:11.00      1          218.6745
2021-09-02 15:57:11.00      1          232.2474
2021-09-02 15:41:19.00      1          238.2798
2021-09-02 15:41:02.00      1          238.2798
2021-09-02 15:35:11.00      0          238.2798
2021-09-02 15:31:14.00      0          238.2798
2021-09-02 14:24:05.00      1          254.3662
2021-09-02 14:23:49.00      1          254.3662
2021-09-02 14:07:43.00      0          254.3662
2021-09-02 12:44:10.00      1          117.6318
2021-09-02 12:43:33.00      1          117.6318
2021-09-02 12:43:22.00      1          117.6318
2021-09-02 12:42:10.00      0          117.6318
2021-09-02 12:41:52.00      0          117.6318
2021-09-02 11:29:38.00      1          141.2587
2021-09-02 07:30:41.00      0          140.2533
2021-09-02 06:22:29.00      1          159.8586
2021-09-02 06:22:10.00      0          159.8586
2021-09-02 06:21:17.00      0          159.8586
2021-09-02 06:20:27.00      0          159.8586
2021-09-02 05:17:14.00      1          181.4747
2021-09-02 04:59:37.00      0          181.4747
2021-09-02 03:37:22.00      1          208.1178
2021-09-02 03:24:31.00      0          208.1178
2021-09-02 00:48:34.00      1          251.35   
2021-09-02 00:39:09.00      0          251.35   
2021-09-02 00:03:09.00      1          251.35   
2021-09-02 00:02:10.00      1          251.35   
2021-09-02 00:01:11.00      1          251.35   
2021-09-02 00:00:10.00      1          251.35   

这就是所谓的间隙和孤岛问题。

因为你只有两个状态,你可以只寻找从 01 的转换。随着时间的推移,总结会给你一个 'partition_id';每个分区以连续的 1 开始并以连续的 0 结束。

有了这些组后,条件聚合将找到组中的前 1 个(开启)和组中的前 0 个(关闭)。

WITH
  transitions AS
(
  SELECT
    vehiclehistorytable.*,
    CASE WHEN LAG(ignition) OVER (ORDER BY timestamp) = ignition OR ignition = 0 THEN 0 ELSE 1 END   AS switch_on
  FROM
    vehiclehistorytable
),
  ignition_phases AS
(
  SELECT
    transitions.*,
    SUM(switch_on) OVER (ORDER BY timestamp)   AS partition_id
  FROM
    transitions
)
SELECT
  MIN(CASE WHEN ignition = 1 THEN timestamp END)   AS ignition_on,
  MIN(CASE WHEN ignition = 0 THEN timestamp END)   AS ignition_off
FROM
  ignition_phases
GROUP BY
  partition_id
ORDER BY
  partition_id

如果您想知道当时的交易量,请在第一个 cte 中添加检查 switch_off 发生的时间...

WITH
  transitions AS
(
  SELECT
    vehiclehistorytable.*,
    CASE WHEN LAG(ignition) OVER (ORDER BY timestamp) = ignition OR ignition = 0 THEN 0 ELSE 1 END   AS switch_on,
    CASE WHEN LAG(ignition) OVER (ORDER BY timestamp) = ignition OR ignition = 1 THEN 0 ELSE 1 END   AS switch_off
  FROM
    vehiclehistorytable
),
  ignition_phases AS
(
  SELECT
    transitions.*,
    SUM(switch_on) OVER (ORDER BY timestamp)   AS partition_id
  FROM
    transitions
)
SELECT
  MIN(CASE WHEN switch_on  = 1 THEN timestamp END)   AS ignition_on,
  MIN(CASE WHEN switch_on  = 1 THEN volume    END)   AS ignition_on_volume,
  MIN(CASE WHEN switch_off = 1 THEN timestamp END)   AS ignition_off, 
  MIN(CASE WHEN switch_off = 1 THEN volume    END)   AS ignition_off_volume
FROM
  ignition_phases
GROUP BY
  partition_id
ORDER BY
  partition_id

编辑: 处理来自 LAG()

的 NULL 的反转逻辑

演示:https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=04a5ee6c62671cde5884a392831e0f16