我想根据日期和时间对表格进行排序。我的数据库在日期和时间上有两个单独的列,它们分别存储为字符串dd-MM-yyyy和HH:mm am / pm。如何对它们进行排序,以便最新条目显示在顶部?
答案 0 :(得分:2)
您存储在数据库中的日期格式不具有可比性,因此您将始终必须处理此类问题。
最好将日期格式更改为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 :(得分:1)
我相信以下内容可以满足您的要求(假设表的名称为 mytable ,日期列的名称为 the_date ,时间列的名称为 the_time (显然会相应地更改这些值):-
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 pm 解析为24:00(也就是说,当对 pm 进行编码时,每小时会增加12点(因此即使32:00 pm将被转换(这样),并视为第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
;
如果日期是使用YYYY-MM-DD HH:MM(或任何公认的格式Date And Time Functions - Time Strings)存储的,则只需对列进行排序(仅需要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):-
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
结果是:-
WHERE the_date BETWEEN '2019-01-01' AND '2019-03-31'
仅选择2019年前3个月的3行(从上述行中)。