用于检索同一表中包含的不同数据系列的SQL查询

时间:2011-10-05 13:43:35

标签: sql sqlite

我试图检索表格中包含的基本上如下所示的数据系列:

row | timestamp | seriesId | int32 | int64 | double
---------------------------------------------------
  0 |         0 |        0 |     2 |       |
  1 |         1 |        0 |     4 |       |
  2 |         1 |        1 |   435 |       |
  3 |         1 |        2 |       |  2345 |
  4 |         1 |        3 |       |       |    0.5
  5 |         2 |        0 |     5 |       |
  6 |         2 |        1 |   453 |       |
  7 |         2 |        2 |       |  2401 |
  ....

我想得到一个看起来像这样的结果集(以便我可以很容易地绘制它):

row | timestamp | series0 | series1 | series 2 | ...
----------------------------------------------------
  0 |         0 |       2 |         |          |
  1 |         1 |       4 |     435 |     2345 |
  2 |         2 |       5 |     453 |     2401 |
...

遗憾的是,我的SQL技能不是他们应该做的,所以我第一次尝试实现这一点感觉有点尴尬:

SELECT tbl0.timestamp, tbl0.int32 as series0,
       tbl1.int32 as series1
FROM
      (SELECT * FROM StreamData WHERE seriesId=0) as tbl0
    INNER JOIN
      (SELECT * FROM StreamData WHERE seriesId=1) as tbl1
    ON tbl0.timestamp = tbl1.timestamp
ORDER BY tbl0.timestamp;

这似乎并不是尝试实现这一目标的正确方法,尤其是当不同系列的数量增加时。我可以改变数据存储在表中的方式(如果这很重要,它会在SQLite数据库中存储),如果这会使事情变得更容易,但由于不同系列的数量可能会不时变化,我宁愿将它们全部放在同一张桌子上。

有没有更好的方法来编写上述查询?

3 个答案:

答案 0 :(得分:2)

似乎你必须使用“group by”:

SELECT row, timestamp, count(seriedIS) AS series0, sum(int32) AS series1, sum(int64) AS series2
FROM StreamData
WHERE (streamId=0) OR (streamId=1)
GROUP BY (timestamp)
ORDER BY timestamp;

试试吧!

答案 1 :(得分:1)

只有当你知道你在那里存储了多少个系列时,它才会起作用。因此压缩INT32,INT64和DOUBLE可以很好地工作。但是,由于你可以拥有任意数量的SeriesID,因此存在问题。

以下是如何压缩可空列(忽略SeriesID的存在)。

SELECT
  timestamp,
  MAX(int32)             AS series0,
  MAX(int64)             AS series1,
  MAX(double)            AS series2
FROM
  StreamData
GROUP BY
  timestamp


如果您知道系列的确切数量,可以按照以下方式进行修改......

SELECT
  timestamp,
  MAX(CASE WHEN seriesID = 0 THEN int32  ELSE NULL END)             AS series0,
  MAX(CASE WHEN seriesID = 1 THEN int64  ELSE NULL END)             AS series1,
  MAX(CASE WHEN seriesID = 2 THEN double ELSE NULL END)             AS series2,
  MAX(CASE WHEN seriesID = 3 THEN int32  ELSE NULL END)             AS series3,
  MAX(CASE WHEN seriesID = 4 THEN int64  ELSE NULL END)             AS series4,
  MAX(CASE WHEN seriesID = 5 THEN double ELSE NULL END)             AS series5
FROM
  StreamData
GROUP BY
  timestamp


但是如果你想让SQL自己完成所有这些工作,那就是任意数量的系列。您必须编写编写所需SQL的代码。

答案 2 :(得分:1)

如果您的seriesId可能有可变数量,则需要动态组装SQL查询。它必须如下所示:

select 
    TimeStamp,
    Max(case seriesId when 0 then coalesce(int32, int64) else null end) series0,
    Max(case seriesId when 1 then coalesce(int32, int64) else null end) series1,
    Max(case seriesId when 2 then coalesce(int32, int64) else null end) series2,
    Max(case seriesId when 3 then coalesce(int32, int64) else null end) series3,
    Max(case seriesId when 4 then coalesce(int32, int64) else null end) series4,
    Max(case seriesId when 5 then coalesce(int32, int64) else null end) series5,
    Max(case seriesId when 6 then coalesce(int32, int64) else null end) series6
from StreamData 
group by TimeStamp
order by TimeStamp

同样根据您的数据样本,我了解您会获得int32int64,具体取决于int32无效,因此coalesce