返回
穿越时空,打卡全年——SQL数据仓库中的时间场景妙技
后端
2023-01-12 22:41:53
穿越时空,打卡全年:数据仓库中的时间场景妙技
时间场景:数据分析中的难题
数据仓库中的时间操作是数据分析的关键,但复杂的时间场景往往令分析师头疼不已。本文将带你轻松掌握多种场景下的 SQL 写法,助你成为数据仓库达人!
场景一:闰年判断
闰年是四年一度的 2 月 29 日,如何判断某一年是否是闰年呢?
SELECT
CASE
WHEN strftime('%m-%d', '2023-02-28') = '02-29' THEN '是闰年'
ELSE '不是闰年'
END AS is_leap_year;
场景二:日期提取
提取日期的各个组成部分,比如年、月、日等,可以方便地进行时间分析。
-- 提取年
SELECT strftime('%Y', '2023-03-08') AS year;
-- 提取月
SELECT strftime('%m', '2023-03-08') AS month;
-- 提取月初
SELECT date('2023-03-01') AS month_start;
-- 提取月末
SELECT date('2023-03-31') AS month_end;
-- 提取周
SELECT strftime('%W', '2023-03-08') AS week;
-- 提取日
SELECT strftime('%d', '2023-03-08') AS day;
-- 提取时
SELECT strftime('%H', '2023-03-08 12:34:56') AS hour;
-- 提取分
SELECT strftime('%M', '2023-03-08 12:34:56') AS minute;
-- 提取秒
SELECT strftime('%S', '2023-03-08 12:34:56') AS second;
场景三:区间查询
区间查询可以过滤出特定时间段内的数据,例如查询某个月份或某段时间的记录。
-- 查询2023年3月的所有日期
SELECT * FROM table_name WHERE date BETWEEN '2023-03-01' AND '2023-03-31';
-- 查询2023年3月的每个星期一
SELECT * FROM table_name WHERE strftime('%w', date) = '1' AND strftime('%Y-%m', date) = '2023-03';
场景四:季度划分
季度是时间分析中常用的概念,如何获取某个年份的季度开始和结束日期呢?
-- 获取2023年第一季度开始和结束日期
SELECT date('2023-01-01'), date('2023-03-31');
-- 获取2023年所有季度的开始和结束日期
SELECT
date(strftime('%Y-%m-01', date('2023-01-01', '+3 months', '-1 day'))),
date(strftime('%Y-%m-01', date('2023-12-31', '+3 months', '-1 day')))
FROM
generate_series(1, 4);
场景五:空值处理
时间数据中经常会出现空值,如何处理空值呢?
-- 将招聘人数为空的月份填充为0
SELECT
strftime('%Y-%m', date) AS month,
COALESCE(SUM(recruitment_count), 0) AS recruitment_count
FROM
table_name
GROUP BY
strftime('%Y-%m', date)
ORDER BY
strftime('%Y-%m', date);
场景六:统计汇总
统计汇总是数据分析中的常见操作,比如统计每隔一段时间的指标变化。
-- 每隔十分钟统计一次数据库登录人数
SELECT
strftime('%Y-%m-%d %H:%M', datetime('now', '-10 minutes', 'localtime')) AS time_interval,
COUNT(*) AS login_count
FROM
login_log
WHERE
datetime(datetime('now', 'localtime'), '-10 minutes') <= datetime
GROUP BY
strftime('%Y-%m-%d %H:%M', datetime('now', '-10 minutes', 'localtime'));
场景七:日历生成
日历是时间场景中的重要工具,如何生成某一年的日历呢?
WITH RecursiveCalendar AS (
SELECT date('2023-01-01') AS date, CAST(strftime('%w', '2023-01-01') AS INTEGER)-7 as dayofweek
UNION ALL
SELECT date(date, '+1 day'), dayofweek+1
FROM RecursiveCalendar
WHERE dayofweek < 355
)
SELECT
date,
strftime('%Y-%m-%d', date) AS formatted_date,
CASE
WHEN dayofweek IN (0, 6) THEN '周末'
ELSE '工作日'
END AS day_type
FROM
RecursiveCalendar
ORDER BY
date;
结语
掌握了这些时间操作技巧,你就能轻松应对数据仓库中各种时间场景的挑战,提高数据分析效率,成为数据仓库达人!
常见问题解答
-
如何判断某一天是星期几?
SELECT strftime('%w', '2023-03-08') AS day_of_week;
-
如何计算两个日期之间的天数?
SELECT date('2023-03-15') - date('2023-03-01') AS days_between;
-
如何获取上个月的最后一天?
SELECT date('2023-03-01', '-1 day', 'start of month') AS last_day_of_previous_month;
-
如何将字符串日期转换为日期类型?
SELECT date('2023-03-08');
-
如何提取某个月的第一个和最后一个工作日?
SELECT date(strftime('%Y-%m-01', '2023-03-01', 'start of month')) AS first_weekday, date(strftime('%Y-%m-01', '2023-03-01', '+1 month', '-1 day'), 'start of day') AS last_weekday;