SQL-запрос для получения различных рядов данных, содержащихся в одной таблице - PullRequest
1 голос
/ 05 октября 2011

Я пытаюсь получить ряд данных, содержащихся в таблице, которая в основном выглядит следующим образом:

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 ]

2 голосов
/ 05 октября 2011

Кажется, вы должны использовать «группировать по»:

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 голос
/ 05 октября 2011

Если у вас есть потенциально переменное число 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

Также из вашего образца данных я понял, что вы получаете либо int32, либо int64, в зависимости от значения int32, то есть coalesce.

1 голос
/ 05 октября 2011

Это будет работать, только если вы знаете, сколько серий вы там сохранили. Таким образом, сжатие INT32, INT64 и DOUBLE down будет работать нормально. Но поскольку у вас может быть любое количество 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...