Попытка «выбрать» предметы из базы данных sqLite на один день [iOS / Mac OS] - PullRequest
0 голосов
/ 05 сентября 2018

Итак, я бился головой о несколько стен на этой стене (и искал ответы здесь и в других местах).

Ниже приведены поиски, которые я использовал, чтобы приблизиться к тому, что я пытаюсь закончить.

Я действительно новичок в sqLite / database, извините заранее, если я не совсем понимаю.

Ниже я попробовал:

datetime(1536115105.62894, 'unixepoch'); -- used this to test the timestamps

SELECT strftime('%Y-%m-%d 23:59', 'now', 'localtime'); --- grabs todays date, localtime, sets to 11:59pm

SELECT strftime('%Y-%m-%d 23:59', 'now', 'localtime'); --- grabs todays date, localtime, sets to 00:00am

SELECT * FROM transactions WHERE timestamps BETWEEN strftime('%Y-%m-%d 23:59', 'now', 'localtime') AND strftime('%Y-%m-%d 23:59', 'now', 'localtime'); --- returns nothing.

SELECT * FROM transactions WHERE timestamps > strftime('%Y-%m-%d 00:00', 'now', 'localtime'); -- returns nothing.

SELECT * FROM transactions WHERE timestamps < strftime('%Y-%m-%d 00:00', 'now', 'localtime'); -- returns everything, which is confusing as there are transactions after this time?

.schema для «транзакций»

CREATE TABLE transactions (id INTEGER PRIMARY KEY, amounts INTEGER(20), timestamps INTEGER(20));

Данные / таблица «транзакции» ниже.

id          amounts     timestamps      
----------  ----------  ----------------
1           450         1536115105.62894
2           450         1536115105.62894
3           450         1536115105.62894
4           551         1536115603.29054
5           10431       1536115603.29054
6           20004       1536115603.29054
7           450         1536115603.29054
8           123         1536115603.29054
9           1244        1536115603.29054
10          201         1536119203      
11          1100        1536118253.46948
12          1100        1536118253.46948
13          1100        1535599853      
14          1100        1535599853      
15          1100        1535599853      
16          123         1535945759      
17          1200        1536032309      
18          450         1536161578      
19          450         1536161578      
20          450         1536161578      
21          100         1536507178      
22          100         1536507178      
23          100         1536507178      
24          25          1534260778      
25          25          1534260778      
26          25          1534260778      

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Я полагаю, что следующее может быть основой для решения. В основном он преобразует значения даты / времени в один и тот же формат для сравнения.

Преобразует столбец timestamp в формат datetime (гггг-мм-дд чч: мм: сс) для сравнения: -

SELECT *
FROM transactions 
WHERE datetime(timestamps,'unixepoch') BETWEEN '2018-09-05 02:00' AND '2018-09-05 23:59'
;

Преобразует значения для сравнения с форматом timestamp (отбрасывает тысячные): -

SELECT *
FROM transactions 
WHERE timestamps BETWEEN strftime('%s', '2018-09-05 02:00') AND strftime('%s', '2018-09-05 23:59')
;
  • Обратите внимание на местное время, использование «сейчас» убрано для простоты.

Вот полный SQL, который был использован для проверки выше: -

DROP TABLE If EXISTS transactions;
CREATE TABLE IF NOT EXISTS transactions (id INTEGER PRIMARY KEY, amounts INTEGER(20), timestamps INTEGER(20));
INSERT INTO transactions (amounts, timestamps) VALUES
    (450,1536115105.62894),
    (450,1536115105.62894),
    (450,1536115105.62894),
    (551,1537115603.29054)
    ;

SELECT *, 
    datetime(timestamps,'unixepoch') AS dt,
    strftime('%Y-%m-%d 02:00','2018-09-05') AS cmprtime1,
    strftime('%Y-%m-%d 23:59','2018-09-05') AS cmprtime2,
    strftime('%s','2018-09-05 02:00') AS cmprts1,
    strftime('%s','2018-09-05 23:59') AS cmprts2
FROM transactions;

SELECT *
FROM transactions 
WHERE datetime(timestamps,'unixepoch') BETWEEN '2018-09-05 02:00' AND '2018-09-05 23:59'
;

SELECT *
FROM transactions 
WHERE timestamps BETWEEN strftime('%s', '2018-09-05 02:00') AND strftime('%s', '2018-09-05 23:59')
;

Результаты выполнения вышеуказанного: -

Первый запрос (показывает преобразованные значения): -

enter image description here

Второй запрос (преобразует столбец отметки времени в формат даты и времени для сравнения) (выбирает 3 из 4): -

enter image description here

Третий запрос (преобразует значения сравнения в метки времени) (выбирает 3 из 4): -

enter image description here

  • Повторюсь, преобразование в местное время / использование сейчас не используется для простоты.
0 голосов
/ 05 сентября 2018

strftime() возвращает строку (например, '2018-09-05 00:00' с некоторыми вашими форматами). Вы сравниваете эту строку с такими вещами, как 1536115105.62894.

Если ваш столбец меток времени объявлен как содержащий РЕАЛЬНЫЕ значения, то sqlite пытается без потерь преобразовать '2018-09-05 00:00' в число, что не удается. А поскольку он не выполняется, он возвращается к неконвертирующему сравнению, где все числовые значения меньше, чем любая строка.

Если временные метки - это столбец TEXT, то '1536115105.62894' будет меньше '2018-09-05 00:00'.

Дополнительная информация .

EDIT:

Итак, если вы хотите сравнить время, вы должны сравнить их в одной и той же форме - как строки, имеющие одинаковый формат (не сравнивайте 'YYYY-mm-DD' с 'HH:MM'), или как числа, означающие одно и то же ( Не сравнивайте юлианские дни с временем в Unix), какую бы форму вы ни предпочли (хотя числа будут более эффективными). Но вы не можете сравнить строку, содержащую читаемое человеком время, с количеством секунд и ожидать, что она просто сработает.

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