【PGCCC】在 Postgres 中创建日期箱的 4 种方法:interval、date_trunc、extract 和 to_char

news2024/11/5 15:49:11

在这篇文章中,我将介绍一些按日期查询数据的关键函数。有关在 Postgres 中存储日期和时间的最佳方法的摘要

interval——日期操纵的瑞士军刀

是interval用于修改其他时间的数据类型。例如,可以从已知时间中添加或减去间隔。间隔非常方便,是您按日期快速汇总数据的第一个方法。就像瑞士军刀一样,它并不总是完成工作的最佳工具,但它可以在紧急情况下使用。让我们谈谈它的优势所在。

我们如何运行查询来返回过去 90 天的订单总额?当然可以使用间隔。如果没有间隔,我们经常看到人们使用从生成日期的外部源传递的日期变量。使用now() - INTERVAL ‘90 days’,无论日期如何,您都可以使用相同的查询。另一个秘诀是使用now()服务器上当前时间的时间戳。

SELECT
  SUM(total_amount)
FROM
  orders
WHERE
  order_date >= NOW () - INTERVAL '90 days';
    sum
-----------
 259472.99
(1 row)

除了使用 之外now(),current_date还可以用来返回日期而不是时间。

SELECT
  SUM(total_amount)
FROM
  orders
WHERE
  order_date >= current_date - INTERVAL '90 days';

这两个查询不同——current_date从一天的开始开始,并now()包含全天的时间。使用时,now()结果将仅匹配当前时间 90 天后发生的结果。

通常,人们使用更短的形式来表示间隔,但这是相同的查询:

SELECT
  SUM(total_amount)
FROM
  orders
WHERE
  order_date >= NOW() - '90 days'::interval;

使用间隔进行分箱

要创建间隔范围,我们可以结合使用CASE和interval。 SQLCASE在查询中执行条件逻辑。 的格式为CASE,WHEN … THEN下面是执行示例 case 语句的查询:

SELECT
  CASE
    WHEN false THEN 'not this'
    WHEN true THEN 'this will show'
    ELSE 'never makes it here'
  END;

现在,让我们将订单按时间范围分类:“30-60 天前”、“60-90 天前”

SELECT
    CASE
        WHEN order_date BETWEEN (NOW() - INTERVAL '60 days') AND (NOW() - INTERVAL '30 days')
            THEN '30-60 days ago'
        WHEN order_date BETWEEN (NOW() - INTERVAL '90 days') AND (NOW() - INTERVAL '60 days')
            THEN '60-90 days ago'
    END AS date_range,
    COUNT(*) AS total_orders,
    SUM(total_amount) AS total_sales
FROM
  orders
WHERE
  order_date BETWEEN (NOW() - INTERVAL '90 days') AND (NOW() - INTERVAL '30 days')
GROUP BY
  date_range
ORDER BY
  date_range;
   date_range   | total_orders | total_sales
----------------+--------------+-------------
 30-60 days ago |          160 |   101754.20
 60-90 days ago |          128 |    88086.24

这可能看起来有点复杂,但该语句的条件是order_date BETWEEN begining_date_value AND ending_date_value。由于CASE语句在第一个真值条件后结束,我们可以进一步简化它:

SELECT
    CASE
	    WHEN order_date >= NOW() - '30 days'::interval THEN '00-30 days ago'
	    WHEN order_date >= NOW() - '60 days'::interval THEN '30-60 days ago'
	    ELSE
		    '60-90 days ago'
	  END AS date_range,
    COUNT(*) AS total_orders,
    SUM(total_amount) AS total_sales
FROM
  orders
WHERE
  order_date >= NOW() - '90 days'::interval
GROUP BY
  date_range
ORDER BY
  date_range;

最好根据 SQL 查询的明确程度来选择模式。使用BETWEEN更明确,可能最适合选择更明确查询的团队。使用困难的部分INTERVAL是最近时间大于较早时间 — 因此,这>=可能会让那些没有使用过大量时间操作的人绞尽脑汁。

总结:用于interval对连续时间进行分箱。

date_trunc - 最简单的日期分箱函数

用于date_trunc对预定义时间进行分箱:如日、周、月、季度和年。间隔逻辑可能很复杂,而date_trunc非常简单。

乍一看,date_trunc的名称可能表明它与格式化有关,但与 结合使用时功能更强大GROUP BY。date_trunc是处理分析时查询工具包的重要组成部分。date_trunc 的简单用法如下:

/* show the beginning of the first day of the month */
SELECT date_trunc('month', current_date);

/* show the beginning of the first day of the week */
SELECT date_trunc('week', current_date);

/* show the beginning of the first day of the year */
SELECT date_trunc('year', current_date);

/* show the beginning of the first day of the current quarter */
SELECT date_trunc('quarter', current_date);

要生成日期箱,请从记录的日期中提取时间段。例如,让我们编写一个查询来显示每月的订单数量和订单总销售额:

SELECT
  date_trunc ('month', order_date) AS month,
  COUNT(*) AS total_orders,
  SUM(total_amount) AS monthly_total
FROM
  orders
GROUP BY 1
ORDER BY
  month;

结果如下:

        month        | total_orders | monthly_total
---------------------+--------------+---------------
 2024-08-01 00:00:00 |           11 |       2699.82
 2024-09-01 00:00:00 |           39 |       8439.41
(2 rows)

使用GROUP BY,Postgres 根据函数返回的唯一值进行计数和求和date_trunc。可用的箱为date_trunc:千年、世纪、十年、年、季度、周、日、小时、分钟、秒、毫秒。

Extract-有时你必须做一些有趣的事情

并非所有日期都能很好地分为日、月、年等。该extract函数提取日期/时间类型的特定值。例如,我通常将extract用于以下情况:

/* returns the epoch value for a date / time    */
/* I this use to send date values to Javascript */
SELECT extract('epoch' from current_date);

/* returns the hour from a time type */
SELECT extract('hour' from now());

如何将其用于对值进行分类?例如,如果您想查找一周中哪一天的哪个小时的订单数量和销售额最高:

SELECT
    extract('dow' from order_date) AS day_of_week,
    extract('hour' from order_date) AS hour,
    COUNT(*) AS total_orders,
    SUM(total_amount) AS monthly_total
FROM
    orders
GROUP BY 1, 2
ORDER BY 1, 2;
 day_of_week | hour | total_orders | monthly_total
-------------+------+--------------+---------------
           0 |   23 |           35 |      23631.56
           1 |    0 |           31 |      19299.88

您会在这里看到星期日是“0”而星期六是“6”。

其中date_trunc保留较高上下文,extract删除除请求的上下文之外的所有上下文。

to_char - 极端改造日期版

它很尴尬,因为to_char它既是日期分箱中最通用的函数,也是最令人讨厌的函数。该函数将接受时间/日期、文本或数字以进行额外的格式化,因此它不是明确用于日期函数的。它从未失败过,当我使用 to_char 时,有人告诉我我可以使用更好的函数。它可以快速生成人类可读的值,但它不适合发送数据进行额外的机器处理。

以下列举几个例子to_char:

/* extract current day of week and current hour of day based on UTC */
SELECT to_char(now(), 'DayHH24');

/* extract current day of week and current hour of day based on NYC time zone */
SELECT to_char(now() AT TIME ZONE 'America/New_York' , 'DayHH24');

这将输出当前星期几以及基于 UTC 时间的当前小时。这让你伤透了脑筋吧?“DayHH24”部分是什么意思?Postgres 文档列出了to_char 使用的保留字符串的长列表:

要更改月份的显示方式,请使用 to_char 提取并格式化名称和年份:

SELECT to_char(order_date, 'FMMonth YYYY') AS formatted_month,
    COUNT(*) AS total_orders,
    SUM(total_amount) AS monthly_total
FROM
    orders
GROUP BY 1
ORDER BY 1;
 formatted_month | total_orders | monthly_total
-----------------+--------------+---------------
 August 2024     |           11 |       2699.82
 September 2024  |           39 |       8439.41

转义保留字符串to_char:

财务中季度的常见格式是“Q1”/“Q2”/“Q3”和“Q4”。使用to_char,我们可以以该格式提取某个时间的季度。但是,“Q”是季度的保留关键字。要打印“Q”而不对其进行评估,请将其括在双引号中:

SELECT
    to_char(order_date, '"Q"Q-YYYY') AS formatted_quarter,
    SUM(total_amount) AS total_amount
FROM
    orders
GROUP BY 1
ORDER BY 1;
 formatted_quarter | total_amount
-------------------+--------------
 Q1-2022           |    313872.84
 Q1-2023           |    282774.15
 Q1-2024           |    287379.33

概括

分箱是财务报告和数据分析中对数据进行分面处理的重要工具。日期和时间是一种比乍一看更复杂的信息——小时、月、小时、季度、年。因此,一个日期可以以多种方式进行分面处理。

幸运的是,Postgres 具有处理日期所需的函数。简要总结如下:

interval- 通过添加/减去修改日期/时间

date_trunc -截断日期/时间 — 本质上是向下舍入到最接近的值

extract- 从日期/时间(日、周、月、季度、年)中提取单条信息

to_char - 将输出格式化为特定样式的日期格式或文本字符串。

作者:Christopher Winslett
链接:https://www.crunchydata.com/blog/4-ways-to-create-date-bins-in-postgres-interval-date_trunc-extract-and-to_char
#PG证书#PG考试#postgresql培训#postgresql考试#postgresql认证

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2233659.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1分钟解决Excel打开CSV文件出现乱码问题

一、编码问题 1、不同编码格式 CSV 文件有多种编码格式,如 UTF - 8、UTF - 16、ANSI 等。如果 CSV 文件是 UTF - 8 编码,而 Excel 默认使用的是 ANSI 编码打开,就可能出现乱码。例如,许多从网络应用程序或非 Windows 系统生成的 …

发布天工AI高级搜索功能,昆仑万维做最懂科研学术的AI搜索

今天,昆仑万维天工AI正式发布最新版本的AI高级搜索功能。 一年时光,栉风沐雨。昆仑万维致力于通过领先的AI技术,为全球用户提供创新的智能搜索和信息处理解决方案。无论是金融、科技领域的专业搜索还是文档分析,「天工AI高级搜索…

mac找到主目录下的文件夹

访达-(上方状态栏显示)-然后在

安装fpm,解决*.deb=> *.rpm

要从生成 .deb 包转换为 .rpm 包,可以按照以下步骤修改打包脚本 1. 使用 fpm 工具 fpm 是一个强大的跨平台打包工具,可以将 .deb 包重新打包成 .rpm,也可以直接从源文件打包成 .rpm。 安装 fpm sudo apt-get install ruby-dev sudo gem in…

分布式光伏管理办法

随着分布式光伏项目的不断增加,传统的管理方式已经难以满足高效、精准的管理需求。光伏业务管理系统作为一种集信息化、智能化于一体的管理工具,正在逐步成为分布式光伏项目管理的重要支撑。 光伏业务管理系统通过数字化手段实现对光伏业务全流程的精细化…

数据结构:LRUCache

什么是LRUCache 首先我们来看看什么是cache 缓存(Cache)通常用于两个速度不同的介质之间,以提高数据访问的速度和效率。这里有几个典型的应用场景: 处理器和内存之间: 处理器(CPU)的运算速度远…

智能提醒助理系列-springboot项目彩虹日志+TraceID

本系列文章记录“智能提醒助理”产品建设历程,记录实践经验、巩固知识点、锻炼总结能力。 本篇介绍如何让springboot启动日志“彩打” 提升日志识别度,同时增加TraceID,便于同一请求,全链路的追踪。 一、需求出发点 提升日志识别度…

窨井监测遥测终端RTU IP68防水强信号穿透力

在窨井的潮湿 黑暗和腐蚀性环境中 常规物联网设备往往难以生存 如何突破层层环境挑战 轻松应对极端条件 确保信号 24h不掉线,不延迟 不仅是对技术的突破 更是对恶劣环境的征服 ↓↓↓ 坚守 ——严苛环境下的工业设备 计讯物联工业级设备,专为恶劣环境设计…

150道MySQL高频面试题,学完吊打面试官--如何实现索引机制

前言 本专栏为150道MySQL大厂高频面试题讲解分析,这些面试题都是通过MySQL8.0官方文档和阿里巴巴官方手册还有一些大厂面试官提供的资料。 MySQL应用广泛,在多个开发语言中都处于重要地位,所以最好都要掌握MySQL的精华面试题,这也…

基于Matlab 模拟停车位管理系统【源码 GUI】

系统对进入停车位的车辆进行车牌识别,将识别出来的车牌号显示出来;然后对车主进行人脸识别,框出车主照片的人脸部分作为车主信息的标记,记录在系统库中。车辆在库期间,系统使用者可以随意查看车辆与车主信息的获取过程…

微信小程序 https://pcapi-xiaotuxian-front-devtest.itheima.net 不在以下 request 合法域名

微信小程序在调用接口的时候出现以上报错,接口没有问题,是因为小程序自动校验了合法域名 打开本地设置: 勾选不校验合法域名,即可 效果如下:

数据治理,数据提取,大数据中心建设,大数据治理总体解决方案书(word,ppt原件)

1. 数据管理的现状 2. 数据治理的概述 1.1数据治理概念 2.2数据治理目标 3. 数据治理体系 4. 数据治理核心领域 1.1 数据模型 1.2 数据生命周期 (1)数据生成及传输 (2)数据存储 (3)数据处理和应用…

电机控制储备知识 二:电磁学理论知识

一:磁场的发现过程和和一些实验现象 古代发现:公元前七世纪,中国和古希腊的学者就已经发现了磁石。 吉尔伯特的研究:1600年,英国女王御臣威廉吉尔伯特(William Gilbert)发表了《地磁论》&#…

Java:数组的定义和使用(万字解析)

目录 1. 数组的概念 2. 数组的基础知识 2.1 数组的创建 \1. 基础创建格式: \2. 类似C语言的创建格式: 【错误的创建(初始化)格式】 2.2 数组的数据类型 2.3 数组的初始化 —— 两种方式 \1.动态初始化:(完全默认初始化) \2. 静态初…

ProLightsfx新的出发–从CSDN到WordPress

原文链接:ProLightsfx新的出发--从CSDN到WordPress_ProLightsfx的技术分享 (https://www.prolightsfxjh.com/article/article-new-start/) 大概有差不多2年时间没有在csdn发布文章了。可能主要是最近几年工作有些疲惫、精神有些懈怠&#xff…

【react】Redux基础用法

1. Redux基础用法 Redux 是一个用于 JavaScript 应用的状态管理库,它不依赖于任何 UI库,但常用于与 React 框架配合使用。它提供了一种集中式的状态管理方式,将应用的所有状态保存在一个单一的全局 Store(存储)中&…

VMware虚拟机Debian扩展磁盘

一、 版本 VMware:Workstation 17 Pro虚拟机:Debian11 二、 VMware虚拟机扩展 虚拟机关机状态快照或者备份:以免扩容失败导致文件丢失虚拟机——设置——硬盘——磁盘使用工具——扩展——扩展磁盘容量——设置为想要的大小 三、 虚拟机…

软件设计师-上午题-16 算法(4-5分)

算法题号一般为62-65题(数据结构与算法题号为57-65,共9分),分值一般为4-5分。 目录 1 回溯法 1.1 N皇后问题 1.2 非递归求解N皇后问题 1.3 递归求解N皇后问题 1.4 真题 2 分治法 2.1 最大字段和问题 2.2 真题 3 动态规划 3.1 0-1背包问题 3.…

【react如何在chrome浏览器里面调试?】

react如何在chrome浏览器里面调试? 1. 首先在在工作区关联源码 2. 安装react的chrome插件。 3. 切换到插件的标签,然后选中你要调试的页面元素,再点击右边的按钮,切换到对应的源码 4. 可以在源码任意位置打断点运行。

【Mysql NDB Cluster 集群(CentOS 7)安装笔记一】

Mysql NDB Cluster 集群(CentOS 7)安装笔记 NDB集群核心概念 NDBCLUSTER(也称为NDB)是一个内存存储引擎,提供高可用性和数据保存功能。 NDBCLUSTER存储引擎可以配置一系列故障转移和负载平衡选项,但从集群级别的存储引擎开始是最容易的。NDB集群的NDB存储引擎包含一整套…