Как отсортировать таблицу sqlite по дате и времени? - PullRequest
0 голосов
/ 03 мая 2019

Я хочу отсортировать свою таблицу по дате и времени. В моей базе данных есть два отдельных столбца для даты и времени, и они хранятся в виде строк dd-MM-yyyy и HH: mm am / pm соответственно. Как мне отсортировать их так, чтобы последняя запись отображалась вверху?

Ответы [ 2 ]

2 голосов
/ 03 мая 2019

Формат дат, которые вы храните в БД: несопоставим , поэтому вам всегда придется сталкиваться с такими проблемами.Лучше измените формат даты на YYYY-MM-DD и времени на hh:mm.В то же время вы можете использовать substr():

select * from tablename
order by 
  substr(datecol, 7) || substr(datecol, 4, 2)  || substr(datecol, 1, 2) DESC, 
  case length(timecol)
    when 8 then substr(timecol, 7) || substr(timecol, 1, 5)
    when 7 then substr('0' || timecol, 7) || substr('0' || timecol, 1, 5)
  end DESC

Изменить datecol и timecol на имена ваших столбцов.Это изменяет формат даты на HHHHMMDD и формат времени на AM/PM mm:HH, и они будут использоваться только в ORDER BY.Как я упоминал ранее, правильным решением будет постоянное изменение форматов даты и времени.

1 голос
/ 04 мая 2019

Я полагаю, что следующее будет работать, как вы пожелаете (при условии, что таблица имеет имя mytable , столбец даты - the_date , а столбец времени - the_time * 1006.* (очевидно, измените эти значения соответственно)): -

SELECT *
FROM mytable 
ORDER BY
    CASE 
        WHEN (substr(the_date,2,1) = '-') AND (substr(the_date,4,1) = '-') THEN substr(the_date,5,4)||'0'||substr(the_date,3,1)||'0'||substr(the_date,1,1)
        WHEN substr(the_date,2,1) = '-' AND substr(the_date,5,1) = '-' THEN substr(the_date,6,4)||substr(the_date,3,2)||'0'||substr(the_date,1,1)
        WHEN substr(the_date,3,1) = '-' AND substr(the_date,5,1) = '-' THEN substr(the_date,6,4)||'0'||substr(the_date,4,1)||substr(the_date,1,2)
      WHEN substr(the_date,3,1) = '-' AND substr(the_date,6,1) = '-' THEN substr(the_date,7,4)||substr(the_date,4,2)||substr(the_date,1,2)
    END DESC
    ,
    CASE
        WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 4 AND instr(the_time,' am') THEN '0'||substr(the_time,1,1)||'0'||substr(the_time,3,1)
        WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' am') THEN '0'||substr(the_time,1,1)||substr(the_time,3,2)  
        WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 4 AND instr(the_time,' pm') THEN CAST(12 + CAST(substr(the_time,1,1) AS INTEGER) AS TEXT)||'0'||substr(the_time,3,1)
        WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' pm') THEN CAST(12 + CAST(substr(the_time,1,1) AS INTEGER) AS TEXT)||substr(the_time,3,2)       
        WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' am') THEN substr(the_time,1,2)||'0'||substr(the_time,4,1)
        WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 6 AND instr(the_time,' am') THEN substr(the_time,1,2)||substr(the_time,4,2)       
        WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' pm') THEN CAST(12 + CAST(substr(the_time,1,2) AS INTEGER) AS TEXT)||'0'||substr(the_time,4,1)
        WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 6 AND instr(the_time,' pm') THEN CAST(12 + CAST(substr(the_time,1,2) AS INTEGER) AS TEXT)||substr(the_time,4,2)
    END DESC
;

Это будет обрабатывать все перестановки одно или двухзначных цифр для дня месяца, месяца года, часов и минут.

Это не волнует 12: 00 вечера это разрешается до 24:00 (то есть когда кодируется pm , к нему добавлено 12 часов (так что даже в 32:00 вечера)будет преобразован (как таковой) и будет рассматриваться как час 44)).00:00 вечера будет таким же, как 12:00 утра (поскольку к часу добавляется 12).

Выше было проверено с использованием: -

DROP TABLE IF EXISTS mytable;
CREATE TABLE IF NOT EXISTS mytable (the_description TEXT, the_date TEXT, the_time TEXT);
INSERT INTO mytable VALUES
    ('REC001','1-1-2019','1:15 am'),
    ('REC002','11-2-2019','11:15 am'),
    ('REC003','2-11-2019','1:15 pm'),
    ('REC004','12-10-2019','11:15 pm'),
    ('REC005','3-2-2019','12:00 am'),
    ('REC006','4-3-2018','12:00 pm'),
    ('REC007','4-3-2018','12:1 am'),
    ('REC008','4-3-2018','1:1 pm')

;
SELECT * FROM mytable;
SELECT *,
    CASE 
        WHEN substr(the_date,2,1) = '-' AND (substr(the_date,4,1) = '-') THEN substr(the_date,5,4)||'0'||substr(the_date,3,1)||'0'||substr(the_date,1,1)
        WHEN substr(the_date,2,1) = '-' AND substr(the_date,5,1) = '-' THEN substr(the_date,6,4)||substr(the_date,3,2)||'0'||substr(the_date,1,1)
        WHEN substr(the_date,3,1) = '-' AND substr(the_date,5,1) = '-' THEN substr(the_date,6,4)||'0'||substr(the_date,4,1)||substr(the_date,1,2)
      WHEN substr(the_date,3,1) = '-' AND substr(the_date,6,1) = '-' THEN substr(the_date,7,4)||substr(the_date,4,2)||substr(the_date,1,2)
    END AS SORTdate,
    CASE
        WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 4 AND instr(the_time,' am') THEN '0'||substr(the_time,1,1)||'0'||substr(the_time,3,1)
        WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' am') THEN '0'||substr(the_time,1,1)||substr(the_time,3,2)  
        WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 4 AND instr(the_time,' pm') THEN CAST(12 + CAST(substr(the_time,1,1) AS INTEGER) AS TEXT)||'0'||substr(the_time,3,1)
        WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' pm') THEN CAST(12 + CAST(substr(the_time,1,1) AS INTEGER) AS TEXT)||substr(the_time,3,2)       
        WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' am') THEN substr(the_time,1,2)||'0'||substr(the_time,4,1)
        WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 6 AND instr(the_time,' am') THEN substr(the_time,1,2)||substr(the_time,4,2)       
        WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' pm') THEN CAST(12 + CAST(substr(the_time,1,2) AS INTEGER) AS TEXT)||'0'||substr(the_time,4,1)
        WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 6 AND instr(the_time,' pm') THEN CAST(12 + CAST(substr(the_time,1,2) AS INTEGER) AS TEXT)||substr(the_time,4,2)
    END AS sorttime
FROM mytable 
ORDER BY
    CASE 
        WHEN (substr(the_date,2,1) = '-') AND (substr(the_date,4,1) = '-') THEN substr(the_date,5,4)||'0'||substr(the_date,3,1)||'0'||substr(the_date,1,1)
        WHEN substr(the_date,2,1) = '-' AND substr(the_date,5,1) = '-' THEN substr(the_date,6,4)||substr(the_date,3,2)||'0'||substr(the_date,1,1)
        WHEN substr(the_date,3,1) = '-' AND substr(the_date,5,1) = '-' THEN substr(the_date,6,4)||'0'||substr(the_date,4,1)||substr(the_date,1,2)
      WHEN substr(the_date,3,1) = '-' AND substr(the_date,6,1) = '-' THEN substr(the_date,7,4)||substr(the_date,4,2)||substr(the_date,1,2)
    END DESC
    ,
    CASE
        WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 4 AND instr(the_time,' am') THEN '0'||substr(the_time,1,1)||'0'||substr(the_time,3,1)
        WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' am') THEN '0'||substr(the_time,1,1)||substr(the_time,3,2)  
        WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 4 AND instr(the_time,' pm') THEN CAST(12 + CAST(substr(the_time,1,1) AS INTEGER) AS TEXT)||'0'||substr(the_time,3,1)
        WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' pm') THEN CAST(12 + CAST(substr(the_time,1,1) AS INTEGER) AS TEXT)||substr(the_time,3,2)       
        WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' am') THEN substr(the_time,1,2)||'0'||substr(the_time,4,1)
        WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 6 AND instr(the_time,' am') THEN substr(the_time,1,2)||substr(the_time,4,2)       
        WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' pm') THEN CAST(12 + CAST(substr(the_time,1,2) AS INTEGER) AS TEXT)||'0'||substr(the_time,4,1)
        WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 6 AND instr(the_time,' pm') THEN CAST(12 + CAST(substr(the_time,1,2) AS INTEGER) AS TEXT)||substr(the_time,4,2)
    END DESC
;

Несортированные строки при первоначальной загрузке: -

enter image description here

Сортированные строки с отображением полей порядка сортировки (преобразованные даты и время): -

enter image description here

Дополнительно

Если даты были сохранены с использованием ГГГГ-ММ-ДД ЧЧ: ММ (или любым из распознанных форматов Функции даты и времени - Строки времени ) тогда вы просто отсортируете по столбцу (потребуется только 1 столбец).Извлечь данные во многих форматах очень просто.

Ниже приведен пример массового обновления, которое преобразует два столбца в один столбец из d (d) -m (m) -yyyy.и формат h (h): m (m) (где заключенные в скобки значения могут существовать или не существовать в зависимости от того, имеет ли значение число десятков или нет).В этом примере оба столбца the_date и the_time преобразуются: -

WITH cte1(cte1id,date,time) AS
    (
        SELECT rowid,
            CASE 
                WHEN substr(the_date,2,1) = '-' AND (substr(the_date,4,1) = '-') 
                    THEN substr(the_date,5,4)||'-0'||substr(the_date,3,1)||'-0'||substr(the_date,1,1)
                WHEN substr(the_date,2,1) = '-' AND substr(the_date,5,1) = '-' 
                    THEN substr(the_date,6,4)||'-'||substr(the_date,3,2)||'-0'||substr(the_date,1,1)
                WHEN substr(the_date,3,1) = '-' AND substr(the_date,5,1) = '-' 
                    THEN substr(the_date,6,4)||'-0'||substr(the_date,4,1)||'-'||substr(the_date,1,2)
                WHEN substr(the_date,3,1) = '-' AND substr(the_date,6,1) = '-' 
                    THEN substr(the_date,7,4)||'-'||substr(the_date,4,2)||'-'||substr(the_date,1,2)
            END AS date,
            CASE
                WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 4 AND instr(the_time,' am') 
                    THEN '0'||substr(the_time,1,1)||':0'||substr(the_time,3,1)
                WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' am') 
                    THEN '0'||substr(the_time,1,1)||':'||substr(the_time,3,2)   
                WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 4 AND instr(the_time,' pm') 
                    THEN CAST(12 + CAST(substr(the_time,1,1) AS INTEGER) AS TEXT)||':0'||substr(the_time,3,1)
                WHEN substr(the_time,2,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' pm') 
                    THEN CAST(12 + CAST(substr(the_time,1,1) AS INTEGER) AS TEXT)||':'||substr(the_time,3,2)        
                WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' am') 
                    THEN substr(the_time,1,2)||':0'||substr(the_time,4,1)
                WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 6 AND instr(the_time,' am') 
                    THEN substr(the_time,1,2)||':'||substr(the_time,4,2)        
                WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 5 AND instr(the_time,' pm') 
                    THEN CAST(12 + CAST(substr(the_time,1,2) AS INTEGER) AS TEXT)||':0'||substr(the_time,4,1)
                WHEN substr(the_time,3,1) = ':' AND instr(the_time,' ') = 6 AND instr(the_time,' pm') 
                    THEN CAST(12 + CAST(substr(the_time,1,2) AS INTEGER) AS TEXT)||':'||substr(the_time,4,2)
            END AS time
        FROM mytable 
        )
UPDATE mytable 
    SET 
        the_date = (SELECT date||' '||time FROM cte1 WHERE cte1id = mytable.rowid),
        the_time = (SELECT date||' '||time FROM cte1 WHERE cte1id = mytable.rowid)
;

Ниже показано, насколько проще становится запрос, кроме того, как получить датуи время, близкое к исходному формату (время не в формате pm pm) из преобразованной таблицы: -

SELECT 
    strftime('%d-%m-%Y %H:%M',the_date) AS old_format, -- Close to original format
    * FROM mytable ORDER BY the_date DESC; -- much simpler to sort

Результат: -

enter image description here

  • столбец old_format - это дата, близкая к исходному формату (но 24 часа)
  • , как видно по столбцам the_date и the_time были преобразованы в формат ГГГГ-ММ-ДД ЧЧ: ММ, и поэтому сортировка по последнему первому является просто вопросом сортировки по столбцу (любому) в порядке убывания.
  • Выбордиапазон дат также очень прост при использовании такого формата, например, WHERE the_date BETWEEN '2019-01-01' AND '2019-03-31' выберет только 3 строки, которые находятся в первые 3 месяца 2019 года (из строк, как указано выше).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...