簡體   English   中英

如何 select 來自 sqlite 文件的連續數據

[英]How to select the continuous data from sqlite file

我在 SQLite 文件中有一些數據,並想從 C# 對其進行操作。

數據包括三列, TimeTemperaturePower 我想找到Temperature高於 30 且持續時間超過 3 分鍾的記錄組,並計算每組的功率平均值(連續時間范圍)。

Select 表中的連續范圍

如何 sql 中的 Select 連續日期

我在上面找到了兩個答案,但無法達到我的答案。

可以使用 SQL 字符串(用於 SQLiteDataAdapter)直接獲取結果。 或 select 所有數據並使用 c#(datatable.Select、計算機或 LINQ)對其進行操作。

| No   | Time              | Temp | Power |
| ---- | ----------------- | ---- | ----- |
| 1    | 2019-11-4 0:00:00 | 25   | 1200  |
| 2    | 2019-11-4 0:01:10 | 30   | 1000  |
| 3    | 2019-11-4 0:02:20 | 31   | 680   |
| 4    | 2019-11-4 0:03:30 | 34   | 960   |
| 5    | 2019-11-4 0:04:40 | 29   | 800   |
| 6    | 2019-11-4 0:05:50 | 31   | 600   |
| 7    | 2019-11-4 0:07:00 | 32   | 400   |
| 8    | 2019-11-4 0:08:10 | 33   | 900   |
| 9    | 2019-11-4 0:09:20 | 34   | 1000  |
| 10   | 2019-11-4 0:10:30 | 39   | 200   |
| 11   | 2019-11-4 0:11:40 | 24   | 350   |

預期結果:select 連續記錄Temp超過 30 和連續時間超過 3 分鍾為一組,並計算Power的平均值。

示例表中的一組,包括從 6 到 10 的編號。平均值為 620。


感謝所有。我的作品中使用的代碼:

        string sql = "WITH CTE AS (" +
                     "SELECT(Temp > 30) AS tempgt30,Time, Power," +
                            "ROW_NUMBER() OVER(ORDER BY No) rn," +
                            "ROW_NUMBER() OVER(PARTITION BY(Temp > 30) ORDER BY No) rn2" +
                     " FROM data" +
                     ")" +
                    " SELECT MIN(rn)AS minrow,MAX(rn) as maxrow," +
                            "strftime('%s', MAX(Time)) - strftime('%s', MIN(Time)) AS duration," +
                            "AVG(Power) AS mean" +
                    " FROM CTE" +
                    " WHERE tempgt30" +
                    " GROUP BY(rn2 - rn)" +
                    " HAVING duration > 180;";

        con.Open();

        if (con.State == ConnectionState.Open)
        {
            using (SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter(sql, con))
            {
                dataAdapter.Fill(datatable);
                con.Close();
            }
        }

您正在查看正確的問題,因為這確實是一個差距和孤島問題。 在您的情況下,“島嶼”是Temp > 30的讀數。 我們可以使用以下查詢形成它們並計算島嶼的Power和持續時間(以秒為單位):

WITH CTE AS (
SELECT (Temp > 30) AS tempgt30, 
       Time,
       Power,
       ROW_NUMBER() OVER (ORDER BY No) rn,
       ROW_NUMBER() OVER (PARTITION BY (Temp > 30) ORDER BY No) rn2
FROM data
)
SELECT MIN(rn) AS minrow, 
       MAX(rn) as maxrow, 
       MIN(Time) AS start,
       MAX(Time) AS end,
       strftime('%s', MAX(Time)) - strftime('%s', MIN(Time)) AS duration,
       AVG(Power) AS mean
FROM CTE
WHERE tempgt30
GROUP BY (rn2 - rn)
HAVING duration > 180

Output:

minrow  maxrow  start                   end                     duration    mean
6       10      2019-11-04 00:05:50     2019-11-04 00:10:30     280         620

dbfiddle 上的演示

我推薦尼克的回答。

下面的腳本是 sql 服務器版本:

你可以使用temptable + cursor來做到這一點。

邏輯:

  • select 進入創建 temptable 並過濾Temp > 30
  • 滯后 function 得到上一個沒有
  • 運行 corsor 檢查是否PreviousNo = CurrentNo - 1然后放入同一組
  • 組有時間分鍾 diff > 3 來獲取數據;

 CREATE TABLE T ([No] int, [Time] datetime, [Temp] int, [Power] int); INSERT INTO T ([No], [Time], [Temp], [Power]) VALUES (1, '2019-11-04 00:00:00', 25, 1200), (2, '2019-11-04 00:01:10', 30, 1000), (3, '2019-11-04 00:02:20', 31, 680), (4, '2019-11-04 00:03:30', 34, 960), (5, '2019-11-04 00:04:40', 29, 800), (6, '2019-11-04 00:05:50', 31, 600), (7, '2019-11-04 00:07:00', 32, 400), (8, '2019-11-04 00:08:10', 33, 900), (9, '2019-11-04 00:09:20', 34, 1000), (10, '2019-11-04 00:10:30', 39, 200), (11, '2019-11-04 00:11:40', 24, 350); GO
  11 行受影響
with cte as ( select LAG(No, 1,0) OVER (ORDER BY No) AS PreviousNo, null AS GroupId, * from T where Temp > 30 ) select * into #T from cte; GO
  7 行受影響
select * from #T GO
 上一個沒有 | 組ID | 沒有 | 時間 | 溫度 | 電源 ---------: |  ------: |  -: |:------------------ |  ---: |  ----: 0 |  null |  3 |  2019 年 4 月 11 日 00:02:20 |  31 |  680 3 |  null |  4 |  2019 年 4 月 11 日 00:03:30 |  34 |  960 4 |  null |  6 |  2019 年 4 月 11 日 00:05:50 |  31 |  600 6 |  null |  7 |  2019 年 4 月 11 日 00:07:00 |  32 |  400 7 |  null |  8 |  2019 年 4 月 11 日 00:08:10 |  33 |  900 8 |  null |  9 |  2019 年 4 月 11 日 00:09:20 |  34 |  1000 9 |  null |  10 |  2019 年 4 月 11 日 00:10:30 |  39 |  200
 DECLARE @tmp_no int,@groupId int = 1; DECLARE MY_CURSOR CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY FOR SELECT No FROM #T OPEN MY_CURSOR FETCH NEXT FROM MY_CURSOR INTO @tmp_no WHILE @@FETCH_STATUS = 0 BEGIN if not (( select PreviousNo from #T where No = @tmp_no ) = @tmp_no - 1) begin set @groupId = @groupId + 1; end update #T set groupId = @groupId where no = @tmp_no; FETCH NEXT FROM MY_CURSOR INTO @tmp_no END CLOSE MY_CURSOR DEALLOCATE MY_CURSOR GO
  7 行受影響
select * from #T GO
 上一個沒有 | 組ID | 沒有 | 時間 | 溫度 | 電源 ---------: |  ------: |  -: |:------------------ |  ---: |  ----: 0 |  2 |  3 |  2019 年 4 月 11 日 00:02:20 |  31 |  680 3 |  2 |  4 |  2019 年 4 月 11 日 00:03:30 |  34 |  960 4 |  3 |  6 |  2019 年 4 月 11 日 00:05:50 |  31 |  600 6 |  3 |  7 |  2019 年 4 月 11 日 00:07:00 |  32 |  400 7 |  3 |  8 |  2019 年 4 月 11 日 00:08:10 |  33 |  900 8 |  3 |  9 |  2019 年 4 月 11 日 00:09:20 |  34 |  1000 9 |  3 |  10 |  2019 年 4 月 11 日 00:10:30 |  39 |  200
 select convert(varchar(3),min(no)) + ' to ' + convert(varchar(3),max(no)) as no_range,avg(power) as avgpower,min(Time) as mintime,max(Time) as maxtime, datediff(minute,min(Time),max(Time)) timediff from #T group by groupid having datediff(minute,min(Time),max(Time)) > 3 GO
  no_range | 平均功率 | 分鍾 | 最大時間 | 時差:------- |  -------: |:------------------ |:------------------ |  --------: 6 到 10 |  620 |  2019 年 4 月 11 日 00:05:50 |  2019 年 4 月 11 日 00:10:30 |  5

db<> 在這里擺弄

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM